home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-15 | 446.8 KB | 9,657 lines |
-
- University of Amsterdam
-
- Dept. of Social
- Science Informatics
-
- (SWI)
- Roeterstraat 15, 1018
- WB Amsterdam
- The Netherlands
- Tel. (+31) 20 5256121
-
- SSWWII--PPrroolloogg 22..99
-
- RReeffeerreennccee MMaannuuaall
-
- _U_p_d_a_t_e_d _f_o_r _v_e_r_s_i_o_n _2_._9_._9_, _M_a_r_c_h _1_9_9_8
-
- _J_a_n _W_i_e_l_e_m_a_k_e_r
-
- jan@swi.psy.uva.nl
-
- SWI-Prolog is a Prolog implementation based on a subset of
- the WAM (Warren Abstract Machine [Warren, 1983]). SWI-Prolog
- has been designed and implemented such that it can easily
- be modified for experiments with logic programming and the
- relation between logic programming and other programming
- paradigms (such as the object oriented XPCE environment
- [Anjewierden & Wielemaker, 1989]). SWI-Prolog has a rich set
- of built-in predicates and reasonable performance, which makes
- it possible to develop substantial applications in it. The
- current version offers a module system, garbage collection and
- an interface to the C language.
-
- This document gives an overview of the features, system limits
- and built-in predicates.
-
- Copyright Oc 1990--1998, University of Amsterdam
-
-
- CChhaapptteerr 11.. IINNTTRROODDUUCCTTIIOONN
-
-
- 11..11 SSWWII--PPrroolloogg
-
- SWI-Prolog has been designed and implemented to get a Prolog
- implementation which can be used for experiments with logic programming
- and the relation to other programming paradigms. The intention
- was to build a Prolog environment which offers enough power and
- flexibility to write substantial applications, but is straightforward
- enough to be modified for experiments with debugging, optimisation or
- the introduction of non-standard data types. Performance optimisation
- is limited due to the main objectives: portability (SWI-Prolog is
- entirely written in C and Prolog) and modifiability.
-
- SWI-Prolog is based on a very restricted form of the WAM (Warren
- Abstract Machine) described in [Bowen & Byrd, 1983] which defines only
- 7 instructions. Prolog can easily be compiled into this language
- and the abstract machine code is easily decompiled back into Prolog.
- As it is also possible to wire a standard 4-port debugger in the
- WAM interpreter there is no need for a distinction between compiled
- and interpreted code. Besides simplifying the design of the Prolog
- system itself this approach has advantages for program development:
- the compiler is simple and fast, the user does not have to decide
- in advance whether debugging is required and the system only runs
- slightly slower when in debug mode. The price we have to pay is
- some performance degradation (taking out the debugger from the WAM
- interpreter improves performance by about 20%) and somewhat additional
- memory usage to help the decompiler and debugger.
-
- SWI-Prolog extends the minimal set of instructions described in
- [Bowen & Byrd, 1983] to improve performance. While extending this
- set care has been taken to maintain the advantages of decompilation
- and tracing of compiled code. The extensions include specialised
- instructions for unification, predicate invocation, some frequently
- used built-in predicates, arithmetic, and control (;//22, |//22), if-then
- (->//22) and not (\+//11).
-
- This manual does not describe the full syntax and semantics of SWI-
- Prolog, nor how one should write a program in Prolog. These subjects
- have been described extensively in the literature. See [Bratko, 1986],
- [Sterling & Shapiro, 1986], and [Clocksin & Melish, 1987]. For
- more advanced Prolog material see [OKeefe, 1990]. Syntax and
- standard operator declarations confirm to the `Edinburgh standard'.
- Most built in predicates are compatible with those described in
- [Clocksin & Melish, 1987]. SWI-Prolog also offers a number of
- primitive predicates compatible with Quintus Prolog [Qui, 1997] and
- BIM_Prolog [BIM, 1989].
-
- ISO compliant predicates are based on ``Prolog: The Standard'',
- [Deransart _e_t _a_l_., 1996].
-
-
- 11..22 SSttaattuuss
-
- This manual describes version 2.9 of SWI-Prolog. SWI-Prolog has been
- used now for several years. The application range includes Prolog
- course material, meta-interpreters, simulation of parallel Prolog,
- learning systems, natural language processing and two large workbenches
- for knowledge engineering. Although we experienced rather obvious and
- critical bugs can remain unnoticed for a remarkable long period, we can
- assume the basic Prolog system is fairly stable. Bugs can be expected
- in infrequently used builtin predicates.
-
- Some bugs are known to the author. They are described as footnotes in
- this manual.
-
-
- 11..33 SShhoouulldd yyoouu bbee UUssiinngg SSWWII--PPrroolloogg??
-
- There are a number of reasons why you better choose a commercial Prolog
- system, or another academic product:
-
- o _S_W_I_-_P_r_o_l_o_g _i_s _n_o_t _s_u_p_p_o_r_t_e_d
- Although I usually fix bugs shortly after a bug report arrives, I
- cannot promise anything. Now that the sources are provided, you
- can always dig into them yourself.
-
- o _M_e_m_o_r_y _r_e_q_u_i_r_e_m_e_n_t_s _a_n_d _p_e_r_f_o_r_m_a_n_c_e _a_r_e _y_o_u_r _f_i_r_s_t _c_o_n_c_e_r_n_s
- A number of commercial compilers are more keen on memory and
- performance than SWI-Prolog. I do not wish to sacrifice some of
- the nice features of the system, nor its portability to compete on
- raw performance.
-
- o _Y_o_u _n_e_e_d _f_e_a_t_u_r_e_s _n_o_t _o_f_f_e_r_e_d _b_y _S_W_I_-_P_r_o_l_o_g
- In this case you may wish to give me suggestions for extensions.
- If you have great plans, please contact me (you might have to
- implement them yourself however).
-
- On the other hand, SWI-Prolog offers some nice facilities:
-
- o _N_i_c_e _e_n_v_i_r_o_n_m_e_n_t
- This includes `Do What I Mean', automatic completion of atom names,
- history mechanism and a tracer that operates on single key-strokes.
- Interfaces to standard Unix editors are provided, as well as a
- facility to maintain programs (see mmaakkee//00).
-
- o _V_e_r_y _f_a_s_t _c_o_m_p_i_l_e_r
- The compiler handles about 100K bytes per second on a SPARC-II
- processor.
-
- o _T_r_a_n_s_p_a_r_e_n_t _c_o_m_p_i_l_e_d _c_o_d_e
- SWI-Prolog compiled code can be treated just as interpreted code:
- you can list it, trace it, assert to or retract from it, etc.
- This implies you do not have to decide beforehand whether a module
- should be loaded for debugging or not. Also, performance is much
- better than the performance of most interpreters.
-
- o _P_r_o_f_i_l_i_n_g
- SWI-Prolog offers tools for performance analysis, which can be very
- useful to optimise programs. Unless you are very familiar with
- Prolog and Prolog performance considerations this might be more
- helpful than a better compiler without these facilities.
-
- o _F_l_e_x_i_b_i_l_i_t_y
- SWI-Prolog allows for easy and flexible integration with C,
- both Prolog calling C functions as C calling Prolog predicates.
- SWI-Prolog is provided in source form, which implies SWI-Prolog
- can be linked in with another package. Command line options and
- predicates to obtain information from the system and feedback into
- the system are provided.
-
- o _I_n_t_e_g_r_a_t_i_o_n _w_i_t_h _X_P_C_E
- SWI-Prolog offers a tight integration to the Object Ori-
- ented Package for User Interface Development, called XPCE
- [Anjewierden & Wielemaker, 1989]. XPCE allows you to implement
- graphical user interfaces that are source-code compatible over
- Unix/X11 and Win32 (Windows 95 and NT).
-
-
- 11..44 TThhee XXPPCCEE GGUUII ssyysstteemm ffoorr PPrroolloogg
-
- The XPCE GUI system for dynamically typed languages has been with
- SWI-Prolog for a long time. It is developed by Anjo Anjewierden and
- Jan Wielemaker from the department of SWI, University of Amsterdam.
- It aims at a high-productive development environment for graphical
- applications based on Prolog.
-
- Object oriented technology has proven to be a suitable model for
- implementing GUIs, which typically deal with things Prolog is not very
- good at: event-driven control and global state. With XPCE, we
- designed a system that has similar characteristics that make Prolog
- such a powerful tool: dynamic typing, meta-programming and dynamic
- modification of the running system.
-
- XPCE is an object-system written in the C-language. It provides for
- the implementation of methods in multiple languages. New XPCE classes
- may be defined from Prolog using a simple, natural syntax. The body of
- the method is executed by Prolog itself, providing a natural interface
- between the two systems. Below is a very simple class definition.
-
- :- pce_begin_class(prolog_lister, frame,
- "List Prolog predicates").
-
- initialise(Self) :->
- "As the C++ constructor"::
- send(Self, send_super, initialise, 'Prolog Lister'),
- send(Self, append, new(D, dialog)),
- send(D, append,
- text_item(predicate, message(Self, list, @arg1))),
- send(new(view), below, D).
-
- list(Self, From:name) :->
- "List predicates from specification"::
- ( term_to_atom(Term, From)
- -> get(Self, member, view, V),
- pce_open(V, write, Fd),
- set_output(Fd),
- listing(Term),
- close(Fd)
- ; send(Self, report, error, 'Syntax error')
- ).
-
- :- pce_end_class.
-
- test :- send(new(prolog_lister), open).
-
- The 165 built-in classes deal with the meta-environment, data-
- representation and---of course---graphics. The graphics classes
- concentrate on direct-manipulation of diagrammatic representations.
-
- AAvvaaiillaabbiilliittyy.. XPCE runs on most Unixtm platforms, Windows 95 and
- Windows NT. It has been connected to SWI-Prolog, SICStustm and Quintustm
- Prolog as well as some Lisp dialects and C++. The Quintus version is
- commercially distributed and supported as ProWindows-3tm.
-
- IInnffoo.. further information is available from
- http://www.swi.psy.uva.nl/projects/xpce/home.html or by E-mail to
- xpce-request@swi.psy.uva.nl. There is a demo version for Windows 95
- and NT in ftp://swi.psy.uva.nl/pub/xpce/Windows/bin/, and one for
- the i386/Linux system in ftp://swi.psy.uva.nl/pub/xpce/linux. For
- information on ProWindows-3, please see http://www.aiil.co.uk, or
- contact sales@aiil.co.uk.
-
-
- 11..55 VVeerrssiioonn 11..55 RReelleeaassee NNootteess
-
- There are not many changes between version 1.4 and 1.5. The C-sources
- have been cleaned and comments have been updated. The stack memory
- management based on using the MMU has been changed to run on a number
- of System-V Unix systems offering shared memory. Handling dates has
- been changed. All functions handling dates now return a floating
- point number, expressing the time in seconds since January 1, 1970.
- A predicate ccoonnvveerrtt__ttiimmee//88 is available to get the year, month, etc.
- The predicate ttiimmee//66 has been deleted. ggeett__ttiimmee//11 and ccoonnvveerrtt__ttiimmee//88
- together do the same.
-
- From version 1.5, the system is distributed in source form, rather than
- in object form as used with previous releases. This allows users to
- port SWI-Prolog to new machines, extend and improve the system. If
- you want your changes to be incorporated in the next release, please
- indicate all changes using a C-preprocessor flag and send complete
- source files back to me. Difference listings are of no use, as I
- generally won't have exactly the same version around.
-
-
- 11..66 VVeerrssiioonn 11..66 RReelleeaassee NNootteess
-
- Version 1.6 is completely compatible with version 1.5. Some new
- features have been added, the system has been ported to various new
- platforms and there is a provisional interface to GNU Emacs. This
- interface will be improved and documented later.
-
- The WAM virtual-machine interpreter has been modified to use GCC-2's
- support for threaded code.
-
- From version 1.6, the sources are now versioned using the CVS version
- control system.
-
-
- 11..77 VVeerrssiioonn 11..77 RReelleeaassee NNootteess
-
- Version 1.7 integrates the GNU-readline library, offering powerful
- history and command-line editing both using Emacs and vi key-bindings.
-
-
- 11..88 VVeerrssiioonn 11..88 RReelleeaassee NNootteess
-
- Version 1.8 offers a stack-shifter to provide dynamically expanding
- stacks on machines that do not offer operating-system support for
- implementing dynamic stacks.
-
-
- 11..99 VVeerrssiioonn 11..99 RReelleeaassee NNootteess
-
- Version 1.9 offers better portability including an MS-Windows 3.1
- version. Changes to the Prolog system include:
-
- o _R_e_d_e_f_i_n_i_t_i_o_n _o_f _s_y_s_t_e_m _p_r_e_d_i_c_a_t_e_s
- Redefinition of system predicates was allowed silently in older
- versions. Version 1.9 only allows it if the new definition is
- headed by a :- rreeddeeffiinnee__ssyysstteemm__pprreeddiiccaattee//11directive.
-
- o _`_A_n_s_w_e_r_' _r_e_u_s_e
- The toplevel maintains a table of bindings returned by toplevel
- goals and allows for reuse of these bindings by prefixing the
- variables with the $ sign. See section 2.5.
-
- o _B_e_t_t_e_r _s_o_u_r_c_e _c_o_d_e _a_d_m_i_n_i_s_t_r_a_t_i_o_n
- Allows for proper updating of multifile predicates and finding the
- sources of individual clauses.
-
-
- 11..1100 VVeerrssiioonn 22..00 RReelleeaassee NNootteess
-
- Version 2.0 is first of all a freeze of all the features added to the
- various 1.9.x releases. Version 2.0.6 for PC has moved from the WATCOM
- C 32-bit windows extender to Windows NT and runs under Windows 3.1
- using the Win32s NT emulator.
-
- New features offered:
-
- o _3_2_-_b_i_t _V_i_r_t_u_a_l _M_a_c_h_i_n_e
- Removes various limits and improves performance.
-
- o _I_n_l_i_n_e _f_o_r_e_i_g_n _f_u_n_c_t_i_o_n_s
- `Simple' foreign predicates no longer build a Prolog stack-frame,
- but are directly called from the VM. Notably provides a speedup for
- the test predicates such as vvaarr//11, etc.
-
- o _V_a_r_i_o_u_s _c_o_m_p_a_t_i_b_i_l_i_t_y _i_m_p_r_o_v_e_m_e_n_t_s
-
- o _S_t_r_e_a_m _b_a_s_e_d _I_/_O _l_i_b_r_a_r_y
- All SWI-Prolog's I/O is now handled by the stream-package defined
- in the foreign include file SWI-Stream.h. Physical I/O of Prolog
- streams may be redefined through the foreign language interface,
- facilitating much simpler integration in window environments.
-
- Version 2.0.6 offers a few incompatibilities:
-
- o rreettrraaccttaallll//11
- In previous releases, the definition of rreettrraaccttaallll//11 was:
-
- retractall(Term) :-
- retract(Term),
- fail.
- retractall(_).
-
- As from version 2.0.6, rreettrraaccttaallll//11 is implemented as a
- deterministic foreign predicate compatible with Quintus Prolog. It
- behaves as:
-
- retractall(Head) :-
- retract(Head),
- fail.
- retractall(Head) :-
- retract((Head :- _)),
- fail.
- retractall(_).
-
- I.e. the definition behaves the same when handling predicates
- consisting of facts. Clauses with a non-true body will be
- retracted if their head matches.
-
- o _F_o_r_e_i_g_n _i_n_t_e_r_f_a_c_e _t_y_p_e_s
- All foreign interface types now have names ending in _t to lessen
- the chance for conflicts. term, atomic, functor and module have
- #define's for backward compatibility.
-
- o PPLL__rreeggiisstteerr__ffoorreeiiggnn(())
- The attributes is now a bitwise or of the attribute flags rather
- than a 0 terminated list. This has no consequences for predicates
- that have no attributes (99% of them), while predicates with just
- one attribute will generate a compiler warning, but work properly
- otherwise. Predicates with more than one attributes must be
- changed.
-
- o PL_dispatch_events
- This pointer is replaced by PPLL__ddiissppaattcchh__hhooookk(()). A function was
- necessary for the Win32 .DLL interface.
-
-
- 11..1111 VVeerrssiioonn 22..11 RReelleeaassee NNootteess
-
- In addition to several bug fixes, the 2.1 versions provide some new
- features:
-
- o sseettaarrgg//33
- A new predicate sseettaarrgg//33 for extra-logical (destructive) assignment
- to arguments of terms is provided.
-
- o _M_o_d_i_f_i_e_d kkeeyyssoorrtt//22
- kkeeyyssoorrtt//22 is now stable with regard to multiple values on the same
- key. Makes this predicate compatible with SICStus and Quintus.
-
- o _M_o_d_i_f_i_e_d _g_r_a_m_m_a_r _r_u_l_e _e_x_p_a_n_s_i_o_n
- DCG translation of free variables now calls pphhrraassee//33, which has
- been changed slightly to deal with `un-parsing'. Modification is
- probably not complete, but it fixes some problems encountered by
- Michael B"ohlen.
-
- o _E_x_c_e_p_t_i_o_n _h_a_n_d_l_i_n_g
- The top of the runtime stack are automatically dumped on floating
- point exceptions.
-
- o _F_o_r_e_i_g_n _i_n_t_e_r_f_a_c_e
- Added facilities to allow for embedding SWI-Prolog in C
- applications.
-
-
- 11..1122 VVeerrssiioonn 22..55 RReelleeaassee NNootteess
-
- Version 2.5 is an intermediate release on the path from 2.1 to 3.0.
- All changes are to the foreign-language interface, both to user-
- and system predicates implemented in the C-language. The aim is
- twofold. First of all to make garbage-collection and stack-expansion
- (stack-shifts) possible while foreign code is active without the
- C-programmer having to worry about locking and unlocking C-variables
- pointing to Prolog terms. The new approach is closely compatible
- to the Quintus and SICStus Prolog foreign interface using the +term
- argument specification (see their respective manuals). This allows for
- writing foreign interfaces that are easily portable over these three
- Prolog platforms.
-
- According to the current plan, ISO compliant exception handling and
- hooks for source-code debugging will be added before the system will be
- called 3.0.
-
- Apart from various bug fixes listed in the Changelog file, these are
- the main changes since 2.1.0:
-
- o _I_S_O _c_o_m_p_a_t_i_b_i_l_i_t_y
- Many ISO compatibility features have been added: ooppeenn//44,
- arithmetic functions, syntax, etc.
-
- o _W_I_N_3_2
- Many fixes for the Win32 (NT, '95 and win32s) platforms. Notably
- many problems related to pathnames and a problem in the garbage
- collector.
-
- o _P_e_r_f_o_r_m_a_n_c_e
- Many changes to the clause indexing system: added hash-tables,
- lazy computation of the index information, etc.
-
- o _P_o_r_t_a_b_l_e _s_a_v_e_d_-_s_t_a_t_e_s
- The predicate qqssaavvee__pprrooggrraamm//[[11,,22]] allows for the creating of
- machine independent saved-states that load very quickly.
-
-
- 11..1133 VVeerrssiioonn 22..66 RReelleeaassee NNootteess
-
- Version 2.6 provides a stable implementation of the features added in
- the 2.5.x releases, but at the same time implements a number of new
- features that may have impact on the system stability.
-
- o _3_2_-_b_i_t _i_n_t_e_g_e_r _a_n_d _d_o_u_b_l_e _f_l_o_a_t _a_r_i_t_h_m_e_t_i_c
- The biggest change is the support for full 32-bit signed integers
- and raw machine-format double precision floats. The internal
- data representation as well as the arithmetic instruction set and
- interface to the arithmetic functions has been changed for this.
-
- o _E_m_b_e_d_d_i_n_g _f_o_r _W_i_n_3_2 _a_p_p_l_i_c_a_t_i_o_n_s
- The Win32 version has been reorganised. The Prolog kernel is now
- implemented as Win32 DLL that may be embedded in C-applications.
- Two front ends are provided, one for window-based operation and one
- to run as a Win32 console application.
-
- o _C_r_e_a_t_i_n_g _s_t_a_n_d_-_a_l_o_n_e _e_x_e_c_u_t_a_b_l_e_s
- Version 2.6.0 can create stand-alone executables by attaching the
- saved-state to the emulator. See qqssaavvee__pprrooggrraamm//22.
-
-
- 11..1144 VVeerrssiioonn 22..77 RReelleeaassee NNootteess
-
- Version 2.7 reorganises the entire data-representation of the Prolog
- data itself. The aim is to remove most of the assumption on the
- machine's memory layout to improve portability in general and enable
- embedding on systems where the memory layout may depend on invocation
- or on how the executable is linked. The latter is notably a problem
- on the Win32 platforms. Porting to 64-bit architectures should be
- feasible now.
-
- Furthermore, 2.7 lifts the limits on arity of predicates and number of
- variables in a clause considerably and allow for further expansion at
- minimal cost.
-
-
- 11..1155 VVeerrssiioonn 22..88 RReelleeaassee NNootteess
-
- data-representation changes of 2.7.x stable. Version 2.8 exploits the
- changes of of 2.7 to support 64-bit processors like the DEC Alpha. As
- of version 2.8.5, the representation of recorded the terms has changed,
- and terms on the heap are now represented in a compiled format.
- SWI-Prolog no longer limits the use of mmaalllloocc(()) or uses assumptions on
- the addresses returned by this function.
-
-
- 11..1166 VVeerrssiioonn 22..99 RReelleeaassee NNootteess
-
- Version 2.9 is the next step towards version 3.0, improving ISO
- compliance and introducing ISO compliant exception handling. New
- are ccaattcchh//33, tthhrrooww//11, aabboolliisshh//11, wwrriittee__tteerrmm//[[22,,33]], wwrriittee__ccaannoonniiccaall//[[11,,22]]
- and the C-functions PPLL__eexxcceeppttiioonn(()) and PPLL__tthhrrooww(()). The predicates
- ddiissppllaayy//[[11,,22]] and ddiissppllaayyqq//[[11,,22]] have been moved to library(backcomp),
- so old code referring to them will autoload them.
-
- The interface to PPLL__ooppeenn__qquueerryy(()) has changed. The _d_e_b_u_g argument is
- replaced by a bitwise or'ed _f_l_a_g_s argument. The values FALSE and
- TRUE have their familiar meaning, making old code using these constants
- compatible. Non-zero values other than TRUE (1) will be interpreted
- different.
-
-
- 11..1177 AAcckknnoowwlleeddggeemmeennttss
-
- Some small parts of the Prolog code of SWI-Prolog are modified
- versions of the corresponding Edinburgh C-Prolog code: grammar rule
- compilation and wwrriitteeff//22. Also some of the C-code originates from
- C-Prolog: finding the path of the currently running executable and the
- code underlying aabbssoolluuttee__ffiillee__nnaammee//22. Ideas on programming style and
- techniques originate from C-Prolog and Richard O'Keefe's _t_h_i_e_f editor.
- An important source of inspiration are the programming techniques
- introduced by Anjo Anjewierden in PCE version 1 and 2.
-
- I also would like to thank those who had the fade of using the early
- versions of this system, suggested extensions or reported bugs. Among
- them are Anjo Anjewierden, Huub Knops, Bob Wielinga, Wouter Jansweijer,
- Luc Peerdeman, Eric Nombden, Frank van Harmelen, Bert Rengel.
-
- Martin Jansche (jansche@novell1.gs.uni-heidelberg.de) has been so kind
- to reorganise the sources for version 2.1.3 of this manual.
-
- Horst von Brand has been so kind to fix many typos in the 2.7.14
- manual. Thanks!
-
-
- CChhaapptteerr 22.. OOVVEERRVVIIEEWW
-
-
- 22..11 SSttaarrttiinngg SSWWII--PPrroolloogg ffrroomm tthhee UUnniixx SShheellll
-
- It is advised to install SWI-Prolog as `pl' in the local binary
- directory. SWI-Prolog can then be started from the Unix shell by
- typing `pl'. The system will boot from the system's default boot file,
- perform the necessary initialisations and then enter the interactive
- top level.
-
- After the necessary system initialisation the system consults (see
- ccoonnssuulltt//11) the user's initialisation file. This initialisation file
- should be named `.plrc' and reside either in the current directory or
- in the user's home directory. If both exist the initialisation file
- from the current directory is loaded. The name of the initialisation
- file can be changed with the `-f file' option. After loading the
- initialisation file SWI-Prolog executes a user initialisation goal.
- The default goal is a system predicate that prints the banner message.
- The default can be modified with the `-g goal' option. Next the
- toplevel goal is started. Default is the interactive Prolog loop (see
- pprroolloogg//00). The user can overwrite this default with the `-t toplevel'
- option.
-
-
- 22..11..11 CCoommmmaanndd LLiinnee OOppttiioonnss
-
- The full set of command line options is given below:
-
- --hheellpp
- When given as the only option, it summarises the most important
- options.
-
- --vv
- When given as the only option, it summarises the version and the
- architecture identifier.
-
- --aarrcchh
- When given as the only option, it prints the architecture
- identifier (see feature(arch, Arch)) and exits.
-
- --LL_s_i_z_e_[_k_m_]
- Give local stack limit (2 Mbytes default). Note that there is no
- space between the size option and its argument. By default, the
- argument is interpreted in Kbytes. Postfixing the argument with
- m causes the argument to be interpreted in Mbytes. The following
- example specifies 32 Mbytes local stack.
-
- % pl -L32m
-
- A maximum is useful to stop buggy programs from claiming all memory
- resources. -L0 sets the limit to the highest possible value.
-
- --GG_s_i_z_e_[_k_m_]
- Give global stack limit (4 Mbytes default). See -L for more
- details.
-
- --TT_s_i_z_e_[_k_m_]
- Give trail stack limit (4 Mbytes default). This limit is
- relatively high because trail-stack overflows are not often caused
- program bugs. See -L for more details.
-
- --AA_s_i_z_e_[_k_m_]
- Give argument stack limit (1 Mbytes default). The argument stack
- limits the maximum nesting of terms that can be compiled and
- executed. The SWI-Prolog does `last-argument optimisation' to
- avoid many deeply nested structure using this stack. Enlarging
- this limit is only necessary in extreme cases. See -L for more
- details.
-
- --HH_s_i_z_e_[_k_m_]
- Give mmaalllloocc(()) heap limit. The default is to raise the limit as
- high as possible. This option only applies to machines using the
- mmmmaapp(()) function for allocating the Prolog stacks. See -L for more
- details.
-
- --cc _f_i_l_e _._._.
- Compile files into an `intermediate code file'. See section 2.7.
-
- --oo _o_u_t_p_u_t
- Used in combination with -c or -b to determine output file for
- compilation.
-
- --OO
- Optimised compilation. See pplleeaassee//33.
-
- --ff _f_i_l_e
- Use _f_i_l_e as initialisation file instead of `.plrc'. `-f none'
- stops SWI-Prolog from searching for an initialisation file.
-
- --FF _s_c_r_i_p_t
- Selects a startup-script from the SWI-Prolog home directory. The
- script-file is named <_s_c_r_i_p_t>.rc. The default _s_c_r_i_p_t name is
- deduced from the executable, taking the leading alphanumerical
- characters (letters, digits and underscore) from the program-name.
- -F none stops looking for a script. Intended for simple management
- of slightly different versions. One could for example write
- a script iso.rc and then select ISO compatibility mode using
- pl -F iso or make a link from iso-pl to pl.
-
- --gg _g_o_a_l
- _G_o_a_l is executed just before entering the top level. Default is a
- predicate which prints the welcome message. The welcome message
- can thus be suppressed by giving -g true. _g_o_a_l can be a complex
- term. In this case quotes are normally needed to protect it from
- being expanded by the Unix shell.
-
- --tt _g_o_a_l
- Use _g_o_a_l as interactive toplevel instead of the default goal
- pprroolloogg//00. _g_o_a_l can be a complex term. If the toplevel goal
- succeeds SWI-Prolog exits with status 0. If it fails the exit
- status is 1. This flag also determines the goal started by
- bbrreeaakk//00 and aabboorrtt//00. If you want to stop the user from entering
- interactive mode start the application with `-g goal' and give
- `halt' as toplevel.
-
- --ttttyy
- Switches tty control (using ioctl(2)) on (+tty) or off (-tty).
- Normally tty control is switched on. This default depends on
- the installation. You may wish to switch tty control off if
- Prolog is used from an editor such as Emacs. If switched off
- ggeett__ssiinnggllee__cchhaarr//11and the tracer will wait for a return.
-
- --xx _b_o_o_t_f_i_l_e
- Boot from _b_o_o_t_f_i_l_e instead of the system's default boot file. A
- bootfile is a file resulting from a Prolog compilation using the -b
- or -c option or a program saved using qqssaavvee__pprrooggrraamm//[[11,,22]].
-
- --rr _r_e_s_t_o_r_e_f_i_l_e
- Restore a state created by ssaavvee__pprrooggrraamm//[[11,,22]] or ssaavvee//[[11,,22]] using
- the new-style saved-states. Equivalent to restore(restorefile)
- from Prolog.
-
- --pp _a_l_i_a_s_=_p_a_t_h_1_[_:_p_a_t_h_2 _._._._]
- Define a path alias for file_search_path. _a_l_i_a_s is the name of
- the alias, _p_a_t_h_1 _._._. is a : separated list of values for the
- alias. A value is either a term of the form alias(value) or
- pathname. The computed aliases are added to ffiillee__sseeaarrcchh__ppaatthh//22
- using aasssseerrttaa//11, so they precede predefined values for the alias.
- See ffiillee__sseeaarrcchh__ppaatthh//22 for details on using this file-location
- mechanism.
-
- --
- Stops scanning for more arguments, so you can pass arguments for
- your application after this one.
-
- The following options are for system maintenance. They are given for
- reference only.
-
- --bb _i_n_i_t_f_i_l_e _._._.-c _f_i_l_e _._._.
- Boot compilation. _i_n_i_t_f_i_l_e _._._. are compiled by the C-written
- bootstrap compiler, _f_i_l_e _._._. by the normal Prolog compiler.
- System maintenance only.
-
- --dd _l_e_v_e_l
- Set debug level to _l_e_v_e_l. Only has effect if the system is
- compiled with the -DO_DEBUG flag. System maintenance only.
-
-
- 22..22 GGNNUU EEmmaaccss IInntteerrffaaccee
-
- A provisional interface to emacs has been included since version 1.6
- of SWI-Prolog. The interface is based on the freely distributed
- interface delivered with Quintus Prolog. When running Prolog as
- an inferior process under GNU-Emacs, there is support for finding
- predicate definitions, completing atoms, finding the locations of
- compilation-warnings and many more. For details, see the files
- pl/lisp/README and pl/lisp/swi-prolog.el.
-
-
- 22..33 OOnnlliinnee HHeellpp
-
- Online help provides a fast lookup and browsing facility to this
- manual. The online manual can show predicate definitions as well as
- entire sections of the manual.
-
- The online help is displayed from the file library('MANUAL'). The file
- library(helpidx) provides an index into this file. library('MANUAL')
- is created from the LaTeX sources with a modified version of dvitty,
- using overstrike for printing bold text and underlining for rendering
- italic text. XPCE is shipped with library(swi_help), presenting the
- information from the online help in a hypertext window. The feature
- write_help_with_overstrike controls whether or not hheellpp//11 writes its
- output using overstrike to realise bold and underlined output or not.
- If this feature is not set it is initialised by the help library to
- true if the TERM variable equals xterm and false otherwise. If this
- default does not satisfy you, add the following line to ~/.plrc.
-
- :- set_feature(write_help_with_overstrike, true).
-
-
- hheellpp
- Equivalent to help(hheellpp//11).
-
-
- hheellpp((_+_W_h_a_t))
- Show specified part of the manual. _W_h_a_t is one of:
-
- <_N_a_m_e>/<_A_r_i_t_y> give help on specified predicate
- <_N_a_m_e> give help on named predicate with any
- arity or C interface function with that
- name
- <_S_e_c_t_i_o_n> display specified section. section
- numbers are dash-separated numbers: 2-3
- refers to section 2.3 of the manual.
-
- Section numbers are obtained using
- aapprrooppooss//11.
-
- Examples
-
- ?- help(assert). give help on predicate assert
- ?- help(3-4). display section 3.4 of the manual
- ?- help('PL_retry'). give help on interface function
- PPLL__rreettrryy(())
-
-
- aapprrooppooss((_+_P_a_t_t_e_r_n))
- Display all predicates, functions and sections that have _P_a_t_t_e_r_n in
- their name or summary description. Lowercase letters in _P_a_t_t_e_r_n
- also match a corresponding uppercase letter. Example:
-
- ?- apropos(file). Display predicates, functions and sec-
- tions that have `file' (or `File', etc.)
- in their summary description.
-
-
- eexxppllaaiinn((_+_T_o_E_x_p_l_a_i_n))
- Give an explanation on the given `object'. The argument may be any
- Prolog data object. If the argument is an atom, a term of the form
- _N_a_m_e_/_A_r_i_t_y or a term of the form _M_o_d_u_l_e_:_N_a_m_e_/_A_r_i_t_y, explain will
- try to explain the predicate as well as possible references to it.
-
-
- eexxppllaaiinn((_+_T_o_E_x_p_l_a_i_n_, _-_E_x_p_l_a_n_a_t_i_o_n))
- Unify _E_x_p_l_a_n_a_t_i_o_n with an explanation for _T_o_E_x_p_l_a_i_n. Backtracking
- yields further explanations.
-
-
- 22..44 QQuueerryy SSuubbssttiittuuttiioonnss
-
- SWI-Prolog offers a query substitution mechanism similar to that of
- Unix csh (csh(1)), called `history'. The availability of this feature
- is controlled by sseett__ffeeaattuurree//22, using the history feature. By default,
- history is available if the feature readline is false. To enable this
- feature, remembering the last 50 commands, put the following into your
- ~/.plrc file:
-
- :- set_feature(history, 50).
-
- The history system allows the user to compose new queries from those
- typed before and remembered by the system. It also allows to correct
- queries and syntax errors. SWI-Prolog does not offer the Unix csh
- capabilities to include arguments. This is omitted as it is unclear
- how the first, second, etc. argument should be defined.
-
- The available history commands are shown in table 2.1. Figure 2.1
- gives some examples.
- __________________________________________________________
- | !!. |Repeat last query |
-
- | !nr. |Repeat query numbered <_n_r> |
- | !str. |Repeat last query starting with <_s_t_r> |
- | !?str. |Repeat last query holding <_s_t_r> |
- | ^old^new. |Substitute <_o_l_d> into <_n_e_w> of last query |
- | !nr^old^new. |Substitute in query numbered <_n_r> |
- | !str^old^new. |Substitute in query starting with <_s_t_r> |
- | !?str^old^new. |Substitute in query holding <_s_t_r> |
- | h. |Show history list |
-
- |_!h.____________|Show_this_list__________________________ |
-
- Table 2.1: History commands
-
- /staff/jan/.plrc consulted, 0.066667 seconds, 591 bytes
- Welcome to SWI-Prolog (Version \plversion)
-
- Copyright (c) 1993-1996 University of Amsterdam. All rights reserved.
-
- For help, use ?- help(Topic). or ?- apropos(Word).
-
- 1 ?- append("Hello ", "World", L).
-
- L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
-
- Yes
- 2 ?- !!, writef('L = %s\n', [L]).
- append("Hello ", "World", L), writef('L = %s\n', [L]).
- L = Hello World
-
- L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
-
- Yes
- 3 ?- sublist(integer, [3, f, 3.4], L).
-
- L = [3]
-
- Yes
- 4 ?- ^integer^number.
-
- sublist(number, [3, f, 3.4], L).
-
- L = [3, 3.400000]
-
- Yes
- 5 ?- h.
- 1 append("Hello ", "World", L).
- 2 append("Hello ", "World", L), writef('L = %s\n', [L]).
-
- 3 sublist(integer, [3, f, 3.4], L).
- 4 sublist(number, [3, f, 3.4], L).
-
- 5 ?- !2^World^Universe.
- append("Hello ", "Universe", L), writef('L = %s\n', [L]).
- L = Hello Universe
-
- L = [72, 101, 108, 108, 111, 32, 85, 110, 105, 118, 101, 114, 115, 101]
-
- Yes
- 6 ?- halt.
-
- Figure 2.1: Some examples of the history facility
-
-
- 22..44..11 LLiimmiittaattiioonnss ooff tthhee HHiissttoorryy SSyysstteemm
-
- When in top level SWI-Prolog reads the user's queries using
- rreeaadd__hhiissttoorryy//66 rather than rreeaadd//11. This predicate first reads the
- current input stream up to a full stop. While doing so it maps all
- contiguous blank space onto a single space and deletes /* ...*/ and
- % ...<_c_r> comments. Parts between double quotes (") or single quotes
- (') are left unaltered. Note that a Prolog full stop consists of a
- `non-symbol' character, followed by a period (.), followed by a blank
- character. `Symbol' characters are: #$&*+-./:<=>?@^`~. A single
- quote immediately preceded by a digit (0-9) is considered part of the
- <_d_i_g_i_t>'<_d_i_g_i_t>...(e.g. 2'101; binary number 101) sequence.
-
- After this initial parsing the result is first checked for the special
- ^<_o_l_d>^<_n_e_w>.construction. If this fails the string is checked for all
- occurrences of the !, followed by a !, ?, a digit, a letter or an
- underscore. These special sequences are analysed and the appropriate
- substitution from the history list is made.
-
- From the above it follows that it is hard or impossible to correct
- quotation with single or double quotes, comment delimiters and spacing.
-
-
- 22..55 RReeuussee ooff ttoopplleevveell bbiinnddiinnggss
-
- Bindings resulting from the successful execution of a toplevel goal are
- asserted in a database. These values may be reused in further toplevel
- queries as $Var. Only the latest binding is available. Example:
- 1 ?- maplist(plus(1), "hello", X).
-
- X = [105,102,109,109,112]
-
- 2 ?- format('~s~n', [$X]).
- ifmmp
-
- Figure 2.2: Reusing toplevel bindings
-
- Note that variables may be set by executing =//22:
-
- 6 ?- X = statistics.
-
- X = statistics
-
- 7 ?- $X.
- 28.00 seconds cpu time for 183,128 inferences
- 4,016 atoms, 1,904 functors, 2,042 predicates, 52 modules
- 55,915 byte codes; 11,239 external references
-
- Limit Allocated In use
- Heap : 624,820 Bytes
- Local stack : 2,048,000 8,192 404 Bytes
- Global stack : 4,096,000 16,384 968 Bytes
- Trail stack : 4,096,000 8,192 432 Bytes
-
-
- 22..66 OOvveerrvviieeww ooff tthhee DDeebbuuggggeerr
-
- SWI-Prolog has a 6-port tracer, extending the standard 4-port tracer
- [Clocksin & Melish, 1987] with two additional ports. The optional
- _u_n_i_f_y port allows the user to inspect the result after unification of
- the head. The _e_x_c_e_p_t_i_o_n port shows exceptions raised by tthhrrooww//11 or one
- of the built-in predicates. See section 3.8.
-
- The standard ports are called call, exit, redo, fail and unify. The
- tracer is started by the ttrraaccee//00 command, when a spy point is reached
- and the system is in debugging mode (see ssppyy//11 and ddeebbuugg//00) or when an
- exception is raised.
-
- The interactive toplevel goal ttrraaccee//00 means ``trace the next query''.
- The tracer shows the port, displaying the port name, the current depth
- of the recursion and the goal. The goal is printed using the Prolog
- predicate pprriinntt//11 (default), wwrriittee//11 or ddiissppllaayy//11. An example using
- all ports is shown in figure 2.3.
- Yes
- 2 ?- visible(+all), leash(-exit).
-
- Yes
- 3 ?- trace, min([3, 2], X).
- Call: ( 3) min([3, 2], G235) ? creep
- Unify: ( 3) min([3, 2], G235)
- Call: ( 4) min([2], G244) ? creep
- Unify: ( 4) min([2], 2)
-
- Exit: ( 4) min([2], 2)
- Call: ( 4) min(3, 2, G235) ? creep
- Unify: ( 4) min(3, 2, G235)
- Call: ( 5) 3 < 2 ? creep
- Fail: ( 5) 3 < 2 ? creep
- Redo: ( 4) min(3, 2, G235) ? creep
- Exit: ( 4) min(3, 2, 2)
- Exit: ( 3) min([3, 2], 2)
-
- Figure 2.3: Example trace
-
- On _l_e_a_s_h_e_d _p_o_r_t_s (set with the predicate lleeaasshh//11, default are call,
- exit, redo and fail) the user is prompted for an action. All actions
- are single character commands which are executed wwiitthhoouutt waiting for a
- return, unless the command line option -tty is active. Tracer options:
-
- + ((SSppyy))
- Set a spy point (see ssppyy//11) on the current predicate.
-
- - ((NNoo ssppyy))
- Remove the spy point (see nnoossppyy//11) from the current predicate.
-
- / ((FFiinndd))
- Search for a port. After the `/', the user can enter a line to
- specify the port to search for. This line consists of a set of
- letters indicating the port type, followed by an optional term,
- that should unify with the goal run by the port. If no term is
- specified it is taken as a variable, searching for any port of the
- specified type. If an atom is given, any goal whose functor has a
- name equal to that atom matches. Examples:
-
- /f Search for any fail port
- /fe solve Search for a fail or exit port of
- any goal with name solve
- /c solve(a, _) Search for a call to solve/2 whose
-
- first argument is a variable or the
- atom a
- /a member(_, _) Search for any port on mmeemmbbeerr//22.
- This is equivalent to setting a spy
- point on mmeemmbbeerr//22.
-
- . ((RReeppeeaatt ffiinndd))
- Repeat the last find command (see `/')
-
- A ((AAlltteerrnnaattiivveess))
- Show all goals that have alternatives.
-
- C ((CCoonntteexxtt))
- Toggle `Show Context'. If on the context module of the goal is
- displayed between square brackets (see section 4). Default is off.
-
- L ((LLiissttiinngg))
- List the current predicate with lliissttiinngg//11.
-
- a ((AAbboorrtt))
- Abort Prolog execution (see aabboorrtt//00).
-
- b ((BBrreeaakk))
- Enter a Prolog break environment (see bbrreeaakk//00).
-
- c ((CCrreeeepp))
- Continue execution, stop at next port. (Also return, space).
-
- d ((DDiissppllaayy))
- Write goals using the Prolog predicate ddiissppllaayy//11.
-
- e ((EExxiitt))
- Terminate Prolog (see hhaalltt//00).
-
- f ((FFaaiill))
- Force failure of the current goal
-
- g ((GGooaallss))
- Show the list of parent goals (the execution stack). Note that due
- to tail recursion optimization a number of parent goals might not
- exist any more.
-
- h ((HHeellpp))
- Show available options (also `?').
-
- i ((IIggnnoorree))
- Ignore the current goal, pretending it succeeded.
-
- l ((LLeeaapp))
- Continue execution, stop at next spy point.
-
- n ((NNoo ddeebbuugg))
- Continue execution in `no debug' mode.
-
- p ((PPrriinntt))
- Write goals using the Prolog predicate pprriinntt//11 (default).
-
- r ((RReettrryy))
- Undo all actions (except for database and i/o actions) back to the
- call port of the current goal and resume execution at the call
- port.
-
- s ((SSkkiipp))
- Continue execution, stop at the next port of tthhiiss goal (thus
- skipping all calls to children of this goal).
-
- u ((UUpp))
- Continue execution, stop at the next port of tthhee ppaarreenntt goal (thus
- skipping this goal and all calls to children of this goal). This
- option is useful to stop tracing a failure driven loop.
-
- w ((WWrriittee))
- Write goals using the Prolog predicate wwrriittee//11.
-
- The ideal 4 port model as described in many Prolog books
- [Clocksin & Melish, 1987] is not visible in many Prolog implementations
- because code optimisation removes part of the choice- and exit
- points. Backtrack points are not shown if either the goal succeeded
- deterministically or its alternatives were removed using the cut. When
- running in debug mode (ddeebbuugg//00) choice points are only destroyed when
- removed by the cut. In debug mode, tail recursion optimisation is
- switched off.
-
-
- 22..77 CCoommppiillaattiioonn
-
-
- 22..77..11 DDuurriinngg pprrooggrraamm ddeevveellooppmmeenntt
-
- During program development, programs are normally loaded using
- ccoonnssuulltt//11, or the list abreviation. It is common practice to organise
- a project as a collection of source-files and a _l_o_a_d_-_f_i_l_e, a Prolog
- file containing only uussee__mmoodduullee//[[11,,22]] or eennssuurree__llooaaddeedd//11 directives,
- possibly with a definition of the _e_n_t_r_y_-_p_o_i_n_t of the program, the
- predicate that is normally used to start the program. This file is
- often called load.pl. If the entry-point is called _g_o, a typical
- session starts as:
-
- % pl
- <banner>
-
- 1 ?- [load].
- <compilation messages>
-
- Yes
- 2 ?- go.
- <program interaction>
-
- When using Windows, the user may open load.pl from the Windows
- explorer, which will cause plwin.exe to be started in the directory
- holding load.pl. Prolog loads load.pl before entering the toplevel.
-
-
- 22..77..22 FFoorr rruunnnniinngg tthhee rreessuulltt
-
- There are various options if you want to make your program ready for
- real usage. The best choice depends on whether the program is to be
- used only on machines holding the SWI-Prolog development system, the
- size of the program and the operating system (Unix vs. Windows).
-
-
- 22..77..22..11 CCrreeaattiinngg aa sshheellll--ssccrriipptt
-
- Especially on Unix systems and not-too-large applications, writing
- a shell-script that simply loads your application and calls the
- entry-point is often a good choice. A skeleton for the script is given
- below, followed by the Prolog code to obtain the program arguments.
-
- #!/bin/sh
-
- base=<absolute-path-to-source>
- PL=pl
-
- exec $PL -f none -g "load_files(['$base/load'],[silent(true)])" -t go -
- - $*
-
- go :-
- unix(argv(Arguments)),
- append(_SytemArgs, [--|Args], Arguments), !,
- go(Args).
-
- go(Args) :-
- ...
-
- On Windows systems, similar behaviour can be achieved by creating a
- shortcut to Prolog, passing the proper options or writing a .bat file.
-
-
- 22..77..22..22 CCrreeaattiinngg aa ssaavveedd--ssttaattee
-
- For larger programs, as well as for programs that are required run on
- systems that do not have the SWI-Prolog development system installed,
- creating a saved state is the best solution. A saved state is created
- using qqssaavvee__pprrooggrraamm//[[11,,22]] or using the linker plld(1). A saved state
- is a file containing machine-independent intermediate code in a format
- dedicated for fast loading. Optionally, the emulator may be integrated
- in the saved state, creating a single-file, but machine-dependent,
- exectable. This process is descriped in chapter 6.
-
-
- 22..77..22..33 CCoommppiilliillaattiioonn uussiinngg tthhee --cc ccoommmmaannddlliinnee ooppttiioonn
-
- This mechanism is mostly for backward compatibility. It creates files
- in the same format as saved-states created using qqssaavvee__pprrooggrraamm//[[11,,22]],
- but the resulting file is a translation of the source-files read,
- rather than a translation of the state of the machine. Unlike saved
- states, programs created using -c file do not include the Prolog part
- of the development system. The result is very dependent on the local
- SWI-Prolog installation.
-
- The command below is used to compile one or more source-files.
-
- pl [options] [-o output] -c file ...
-
- The individual source files may include other files using the standard
- list notation, ccoonnssuulltt//11, eennssuurree__llooaaddeedd//11and uussee__mmoodduullee//[[11,,22]]. When
- the -o file option is omitted a file named a.out is created that holds
- the intermediate code file.
-
- Intermediate code files start with the Unix magic code #! and are
- executable. This implies they can be started as a command:
-
- % pl -o my_program -c ...
- ...
- % my_program [options]
-
- Alternatively, my_program can be started with
-
- % pl -x my_program [options]
-
- The following restrictions apply to source files that are to be
- compiled with `-c':
-
- o tteerrmm__eexxppaannssiioonn//22 should not use aasssseerrtt//11 and or rreettrraacctt//11 other
- than for local computational purposes.
-
- o Files can only be included by the standard include directives:
- [...], ccoonnssuulltt//11, eennssuurree__llooaaddeedd//11 and uussee__mmoodduullee//[[11,,22]]. User
- defined loading predicate invocations will not be compiled.
-
- Directives are executed both when compiling the program and when
- loading the intermediate code file.
-
-
- 22..88 EEnnvviirroonnmmeenntt CCoonnttrrooll
-
- The current system defines 3 different mechanisms to query and/or set
- properties of the environment: pplleeaassee//33, ffllaagg//33 and ffeeaattuurree//22 as
- well as a number of special purpose predicates of which uunnkknnoowwnn//22,
- ffiilleeeerrrroorrss//22 are examples. The ISO standard defines prolog_flag. It is
- likely that all these global features will be merged into a single in
- the future.
-
-
- pplleeaassee((_+_K_e_y_, _-_O_l_d_, _+_N_e_w))
- The predicate pplleeaassee//33 is a solution to avoid large numbers of
- environment control predicates. Later versions will support
- other environment control as now provided via the predicates
- ssttyyllee__cchheecckk//11, lleeaasshh//11, uunnkknnoowwnn//22, the tracer predicates, etc.
- These predicates are then moved into a library for backwards
- compatibility. The currently available options are:
-
- ooppttiimmiissee _o_n_/_o_f_f (default: _o_f_f_)
- Switch optimise mode for the compiler on or off (see also
- the command line option -O). Currently optimise compilation
- only implies compilation of arithmetic, making it fast,
- but invisible to the tracer. Later versions might imply
- various other optimisations such as incorporating a number
- of basic predicates in the virtual machine (vvaarr//11, ffaaiill//00,
- =/2, etc.) to gain speed at the cost of crippling the
- debugger. Also source level optimisations such as integrating
- small predicates into their callers, eliminating constant
- expressions and other predictable constructs. Source code
- optimisation is never applied to predicates that are declared
- dynamic (see ddyynnaammiicc//11).
-
- aauuttoollooaadd _o_n_/_o_f_f (default: _o_n_)
- If on autoloading of library functions is enabled. If off
- autoloading is disabled. See section 2.9.
-
- vveerrbboossee__aauuttoollooaadd _o_n_/_o_f_f (default: _o_f_f_)
- If on the normal consult message will be printed if a library
- is autoloaded. By default this message is suppressed.
- Intended to be used for debugging purposes (e.g. where does
- this predicate come from?).
-
-
- ffeeaattuurree((_?_K_e_y_, _-_V_a_l_u_e))
- The predicate ffeeaattuurree//22 defines an interface to installation
- features: options compiled in, version, home, etc. With both
- arguments unbound, it will generate all defined features. With the
- `Key' instantiated it unify the value of the feature. Features
- come in three types: boolean features, features with an atom value
- and features with an integer value. A boolean feature is true iff
- the feature is present aanndd the _V_a_l_u_e is the atom true. Currently
- defined keys:
-
- aarrcchh ((_a_t_o_m))
- Identifier for the hardware and operating system SWI-Prolog is
- running on. Used to determine the startup file as well as to
- select foreign files for the right architecture. See also
- llooaadd__ffoorreeiiggnn//55.
-
- vveerrssiioonn ((_i_n_t_e_g_e_r))
- The version identifier is an integer with value:
-
- 10000_*Major+ 100_*Minor+_P_a_t_c_h
-
- Note that in releases upto 2.7.10 this feature yielded
- an atom holding the three numbers separated by dots.
- The current representation is much easier for implementing
- version-conditional statements.
-
- hhoommee ((_a_t_o_m))
- SWI-Prolog's notion of the home-directory. SWI-Prolog
- uses it's home directory to find its startup file as
- <_h_o_m_e>/startup/startup.<_a_r_c_h> and to find its library as
- <_h_o_m_e>/library.
-
- ppiippee ((_b_o_o_l))
- If true, tell(pipe(command)), etc. are supported.
-
- llooaadd__ffoorreeiiggnn ((_b_o_o_l))
- If true, llooaadd__ffoorreeiiggnn//[[22,,55]]are implemented.
-
- ooppeenn__sshhaarreedd__oobbjjeecctt ((_b_o_o_l))
- If true, ooppeenn__sshhaarreedd__oobbjjeecctt//22 and friends are implemented,
- providing access to shared libraries (.so files). This
- requires the C-library functions dlopen() and friends as well
- as the configuration option --with-dlopen.
-
- ddyynnaammiicc__ssttaacckkss ((_b_o_o_l))
- If true, the system uses some form of `sparse-memory manage-
- ment' to realise the stacks. If false, malloc()/realloc() are
- used for the stacks. In earlier days this had consequenses
- for foreign code. As of version 2.5, this is no longer the
- case.
-
- Systems using `sparse-memory management' are a bit faster as
- there is no stack-shifter, and checking the stack-boundary is
- often realised by the hardware using a `guard-page'. Also,
- memory is actually returned to the system after a garbage
- collection or call to ttrriimm__ssttaacckkss//00 (called by pprroolloogg//00 after
- finishing a user-query).
-
- cc__lliibbss ((_a_t_o_m))
- Libraries passed to the C-linker when SWI-Prolog was linked.
- May be used to determine the libraries needed to create
- statically linked extensions for SWI-Prolog. See section 5.7.
-
- cc__ssttaattiicclliibbss ((_a_t_o_m))
- On some machines, the SWI-Prolog executable is dynamically
- linked, but requires some libraries to be statically linked.
- Obsolete.
-
- cc__cccc ((_a_t_o_m))
- Name of the C-compiler used to compile SWI-Prolog. Normally
- either gcc or cc. See section 5.7.
-
- cc__llddffllaaggss ((_a_t_o_m))
- Special linker flags passed to link SWI-Prolog. See
- section 5.7.
-
- ssaavvee ((_b_o_o_l))
- If true, ssaavvee//[[11,,22]] is implemented. Saving using ssaavvee//00 is
- obsolete. See qqssaavvee__pprrooggrraamm//[[11,,22]].
-
- ssaavvee__pprrooggrraamm ((_b_o_o_l))
- If true, ssaavvee__pprrooggrraamm//[[11,,22]] is implemented. Saving using
- ssaavvee__pprrooggrraamm//00is obsolete. See qqssaavvee__pprrooggrraamm//[[11,,22]].
-
- rreeaaddlliinnee ((_b_o_o_l))
- If true, SWI-Prolog is linked with the readline library.
- This is done by default if you have this library installed
- on your system. It is also true for the Win32 plwin.exe
- version of SWI-Prolog, which realises a subset of the readline
- functionality.
-
- ssaavveedd__pprrooggrraamm ((_b_o_o_l))
- If true, Prolog is started from a state saved with
- qqssaavvee__pprrooggrraamm//[[11,,22]].
-
- rruunnttiimmee ((_b_o_o_l))
- If true, SWI-Prolog is compiled with -DO_RUNTIME, disabling
- various useful development features (currently the tracer and
- profiler).
-
- mmaaxx__iinntteeggeerr ((_i_n_t_e_g_e_r))
- Maximum integer value. Most arithmetic operations will
- automatically convert to floats if integer values above this
- are returned.
-
- mmiinn__iinntteeggeerr ((_i_n_t_e_g_e_r))
- Minimum integer value.
-
- mmaaxx__ttaaggggeedd__iinntteeggeerr ((_i_n_t_e_g_e_r))
- Maximum integer value represented as a `tagged' value. Tagged
- integers require 4-bytes storage and are used for indexing.
- Larger integers are represented as `indirect data' and require
- 16-bytes on the stacks (though a copy requires only 4
- additional bytes).
-
- mmiinn__ttaaggggeedd__iinntteeggeerr ((_i_n_t_e_g_e_r))
- Start of the tagged-integer value range.
-
- ffllooaatt__ffoorrmmaatt ((_a_t_o_m))
- C printf() format specification used by wwrriittee//11 and friends
- to determine how floating point numbers are printed. The
- default is %g. May be changed. The specified value is passed
- to printf() without further checking. For example, if you
- want more digits printed, %.12g will print all floats using
- 12 digits instead of the default 6. See also ffoorrmmaatt//[[11,,22]],
- wwrriittee//11, pprriinntt//11 and ppoorrttrraayy//11.
-
- ccoommppiilleedd__aatt ((_a_t_o_m))
- Describes when the system has been compiled. Only available
- if the C-compiler used to compile SWI-Prolog provides the
- __DATE__and __TIME__macros.
-
- cchhaarraacctteerr__eessccaappeess ((_b_o_o_l))
- If true (default), rreeaadd//11 interprets \ escape sequences in
- quoted atoms and strings. May be changed.
-
- aallllooww__vvaarriiaabbllee__nnaammee__aass__ffuunnccttoorr ((_b_o_o_l))
- If true (default is false), Functor(arg) is read as if it
- was written 'Functor'(arg). Some applications use the Prolog
- rreeaadd//11 predicate for reading an application defined script
- language. In these cases, it is often difficult to explain
- none-Prolog users of the application that constants and
- functions can only start with a lowercase letter. Variables
- can be turned into atoms starting with an uppercase atom by
- calling rreeaadd__tteerrmm//22using the option variable_names and binding
- the variables to their name. Using this feature, F(x) can be
- turned into valid syntax for such script languages. Suggested
- by Robert van Engelen. SWI-Prolog specific.
-
- hhiissttoorryy ((_i_n_t_e_g_e_r))
- If >0, support Unix csh(1) like history as described in
- section 2.4. Otherwise, only support reusing commands through
- the commandline editor. The default is to set this feature to
- 0 if a commandline editor is provided (see feature readline)
- and 15 otherwise.
-
- ggcc ((_b_o_o_l))
- If true (default), the garbage collector is active. If false,
- neither garbage-collection, nor stack-shifts will take place,
- even not on explicit request. May be changed.
-
- ttrraaccee__ggcc ((_b_o_o_l))
- If true (false is the default), garbage collections and
- stack-shifts will be reported on the terminal. May be
- changed.
-
- mmaaxx__aarriittyy ((_u_n_b_o_u_n_d_e_d))
- ISO feature describing there is no maximum arity to compound
- terms.
-
- iinntteeggeerr__rroouunnddiinngg__ffuunnccttiioonn ((_d_o_w_n_,_t_o_w_a_r_d___z_e_r_o))
- ISO feature describing rounding by // and rem arithmetic
- functions. Value depends on the C-compiler used.
-
- bboouunnddeedd ((_t_r_u_e))
- ISO feature describing integer representation is bound by
- min_integer and min_integer.
-
- ttttyy__ccoonnttrrooll ((_b_o_o_l))
- Determines whether the terminal is switched to raw mode for
- ggeett__ssiinnggllee__cchhaarr//11, which also reads the user-actions for the
- trace. May be set. See also the +/-tty command-line option.
-
- ddeebbuugg__oonn__eerrrroorr ((_b_o_o_l))
- If true, start the tracer after an error is detected.
- Otherwise just continue execution. The goal that raised the
- error will normally fail. See also ffiilleeeerrrroorrss//22 and the
- feature report_error. May be changed. Default is true, except
- for the runtime version.
-
- rreeppoorrtt__eerrrroorr ((_b_o_o_l))
- If true, print error messages, otherwise suppress them. May
- be changed. See also the debug_on_error feature. Default is
- true, except for the runtime version.
-
- uunniixx ((_b_o_o_l))
- If true, the operating system is some version of Unix.
- Defined if the C-compiler used to compile this version of
- SWI-Prolog either defines __unix__ or unix.
-
- wwiinnddoowwss ((_b_o_o_l))
- If true, the operating system is an implementation of
- Microsoft Windows (3.1, 95, NT, etc.).
-
-
- sseett__ffeeaattuurree((_+_K_e_y_, _+_V_a_l_u_e))
- Define a new feature or change its value. _K_e_y is an atom, _V_a_l_u_e is
- an atom or number.
-
-
- 22..99 AAuuttoommaattiicc llooaaddiinngg ooff lliibbrraarriieess
-
- If ---at runtime--- an undefined predicate is trapped the system will
- first try to import the predicate from the module's default module.
- If this fails the _a_u_t_o _l_o_a_d_e_r is activated. On first activation an
- index to all library files in all library directories is loaded in core
- (see lliibbrraarryy__ddiirreeccttoorryy//11). If the undefined predicate can be located
- in the one of the libraries that library file is automatically loaded
- and the call to the (previously undefined) predicate is resumed. By
- default this mechanism loads the file silently. The pplleeaassee//33 option
- verbose_autoload is provided to get verbose loading. The please option
- autoload can be used to enable/disable the entire auto load system.
-
- Autoloading only handles (library) source files that use the module
- mechanism described in chapter 4. The files are loaded with
- uussee__mmoodduullee//22 and only the trapped undefined predicate will be imported
- to the module where the undefined predicate was called. Each library
- directory must hold a file INDEX.pl that contains an index to all
- library files in the directory. This file consists of lines of the
- following format:
-
- index(Name, Arity, Module, File).
-
- The predicate mmaakkee//00 scans the autoload libraries and updates the
- index if it exists, is writable and out-of-date. It is advised to
- create an empty file called INDEX.pl in a library directory meant for
- auto loading before doing anything else. This index file can then
- be updated by running the prolog mmaakkee__lliibbrraarryy__iinnddeexx//11(`%' is the Unix
- prompt):
-
- % mkdir ~/lib/prolog
- % cd !$
- % pl -g true -t 'make_library_index(.)'
-
- If there are more than one library files containing the desired
- predicate the following search schema is followed:
-
- 1. If a there is a library file that defines the module in which the
- undefined predicate is trapped, this file is used.
-
- 2. Otherwise library files are considered in the order they appear
- in the lliibbrraarryy__ddiirreeccttoorryy//11 predicate and within the directory
- alphabetically.
-
-
- mmaakkee__lliibbrraarryy__iinnddeexx((_+_D_i_r_e_c_t_o_r_y))
- Create an index for this directory. The index is written to the
- file 'INDEX.pl' in the specified directory. Fails with a warning
- if the directory does not exist or is write protected.
-
-
- 22..99..11 NNootteess oonn AAuuttoommaattiicc LLooaaddiinngg
-
- The autoloader is a new feature to SWI-Prolog. Its aim is to simplify
- program development and program management. Common lisp has a similar
- feature, but here the user has to specify which library is to be loaded
- if a specific function is called which is not defined. The advantage
- of the SWI-Prolog schema is that the user does not have to specify
- this. The disadvantage however is that the user might be wondering
- ``where the hell this predicate comes from''. Only experience can
- learn whether the functionality of the autoloader is appropriate.
- Comments are welcome.
-
- The autoloader only works if the unknown flag (see uunnkknnoowwnn//22) is set to
- trace (default). A more appropriate interaction with this flag will be
- considered.
-
-
- 22..1100 GGaarrbbaaggee CCoolllleeccttiioonn
-
- SWI-Prolog version 1.4 was the first release to support garbage
- collection. Together with tail-recursion optimisation this guaranties
- forward chaining programs do not waste indefinite amounts of memory.
- Previous releases of this manual stressed on using failure-driven loops
- in those cases that no information needed to be passed to the next
- iteration via arguments. This to avoid large amounts of garbage. This
- is no longer strictly necessary, but it should be noticed that garbage
- collection is a time consuming activity. Failure driven loops tend to
- be faster for this reason.
-
-
- 22..1111 SSyynnttaaxx NNootteess
-
- SWI-Prolog uses standard `Edinburgh' syntax. A description of this
- syntax can be found in the Prolog books referenced in the introduction.
- Below are some non-standard or non-common constructs that are accepted
- by SWI-Prolog:
-
- o 0'<_c_h_a_r>
- This construct is not accepted by all Prolog systems that claim to
- have Edinburgh compatible syntax. It describes the ASCII value of
- <_c_h_a_r>. To test whether C is a lower case character one can use
- between(0'a, 0'z, C).
-
- o /* .../* ...*/ ...*/
- The /* ...*/ comment statement can be nested. This is useful
- if some code with /* ...*/ comment statements in it should be
- commented out.
-
-
- 22..1111..11 IISSOO SSyynnttaaxx SSuuppppoorrtt
-
- SWI-Prolog offers ISO compatible extensions to the Edinburgh syntax.
-
-
- 22..1111..11..11 CChhaarraacctteerr EEssccaappee SSyynnttaaxx
-
- Within quoted atoms (using single quotes: '<_a_t_o_m>'special characters
- are represented using escape-sequences. An escape sequence is lead
- in by the backslash (\) character. The list of escape sequences
- is compatible with the ISO standard, but contains one extension and
- the interpretation of numerically specified characters is slightly more
- flexible to improve compatibility.
-
- \a
- Alert character. Normally the ASCII character 7 (beep).
-
- \b
- Backspace character.
-
- \c
- No output. All input characters upto but not including the
- first non-layout character are skipped. This allows for the
- specification of pretty-looking long lines. For compatibility with
- Quintus Prolog. Nor supported by ISO. Example:
-
- format('This is a long line that would look better if it was \c
- split across multiple physical lines in the input')
-
- \<RETURN>
- No output. Skips input till the next non-layout character or to
- the end of the next line. Same intention as \c but ISO compatible.
-
- \f
- Form-feed character.
-
- \n
- Next-line character.
-
- \r
- Carriage-return only (i.e. go back to the start of the line).
-
- \t
- Horizontal tab-character.
-
- \v
- Vertical tab-character (ASCII 11).
-
- \x23
- Hexadecimal specification of a character. 23 is just an example.
- The `x' may be followed by a maximum of 2 hexadecimal digits.
- The closing \ is optional. The code \xa\3 emits the character
- 10 (hexadecimal `a') followed by `3'. The code \x201 emits 32
- (hexadecimal `20') followed by `1'. According to ISO, the closing
- \ is obligatory and the number of digits is unlimited. The
- SWI-Prolog definition allows for ISO compatible specification, but
- is compatible with other implementations.
-
- \40
- Octal character specification. The rules and remarks for
- hexadecimal specifications apply to octal specifications too, but
- the maximum allowed number of octal digits is 3.
-
- \<_c_h_a_r_a_c_t_e_r>
- Any character immediately preceded by a \ is copied verbatim.
- Thus, '\\' is an atom consisting of a single \ and '\'' and ''''
- both describe the atom with a single '.
-
- Character escaping is only available if the
- feature(character_escapes, true) is active (default). See ffeeaattuurree//22.
- Character escapes conflict with wwrriitteeff//22 in two ways: \40 is
- interpreted as decimal 40 by wwrriitteeff//22, but character escapes handling
- by read has already interpreted as 32 (40 octal). Also, \l is
- translated to a single `l'. Double the \ (e.g. \\, use the above
- escape sequences or use ffoorrmmaatt//22.
-
-
- 22..1111..11..22 SSyynnttaaxx ffoorr NNoonn--DDeecciimmaall NNuummbbeerrss
-
- SWI-Prolog implements both Edinburgh and ISO representations for
- non-decimal numbers. According to Edinburgh syntax, such numbers are
- written as <_r_a_d_i_x>'<_n_u_m_b_e_r>, where <_r_a_d_i_x> is a number between 2 and 36.
- ISO defines binary, octal and hexadecimal numbers using 0[bxo]<_n_u_m_b_e_r>.
- For example: A is 0b100 \/ 0xf00 is a valid expression. Such numbers
- are always unsigned.
-
-
- 22..1122 SSyysstteemm LLiimmiittss
-
-
- 22..1122..11 LLiimmiittss oonn MMeemmoorryy AArreeaass
-
- SWI-Prolog has a number of memory areas which are only enlarged to a
- certain limit. The default sizes for these areas should suffice for
- most applications, but big applications may require larger ones. They
- are modified by command line options. The table below shows these
- areas. The first column gives the option name to modify the size of
- the area. The option character is immediately followed by a number and
- optionally by a k or m. With k or no unit indicator, the value is
- interpreted in Kbytes (1024 bytes), with m, the value is interpreted in
- Mbytes (10241* 024 bytes).
-
- The local-, global- and trail-stack are limited to 64 Mbytes on 32
- bit processors, or more in general to 2 to the power bits-per-long - 6
- bytes.
- ___________________________________________________________
- |_Option_|Default_|Area_name______|Description____________|_||-L||2Mllooccaa||llTssttaacckkhe|l||||ocal|stack is used
-
- | | to store the execu- | | ||
- | | tion environments of | | ||
- | | procedure invocations. | | ||
- | | The space for an en- | | ||
- | | vironment is reclaimed | | ||
- | | when it fails, exits | | ||
- | | without leaving choice | | ||
- | | points, the alterna- | | ||
- | | tives are cut of with | | ||
- | | | | ||
-
- | | the !/0 predicate or | | ||
- | | no choice points have | | ||
- | | been created since the | | ||
- | | invocation and the last | | ||
- | | subclause is started | | ||
- | | (tail recursion optimi- | | ||
- || || | ||sation). || | ||
-
- | -G | 4M |gglloobbaall ssttaacckk ||Theusglobaled stacktois store| terms
- | | | ||created during Prolog's |
- | | | ||execution. Terms on |
- | | | || |
- | | | ||this stack will be re- |
- | | | ||claimed by backtracking |
- | | | ||to a point before the |
- | | | ||term was created or |
- | | | ||by garbage collection |
-
- | | | ||(provided the term is |
- || || || ||no||longer referenced). ||
- | -T | 4M |ttrraaiill ssttaacckk ||Theusetraild stackto isstore| as-
- | | | ||signments during execu- |
- | | | || |
- | | | ||tion. Entries on this |
- | | | ||stack remain alive un- |
-
- | | | ||til backtracking before |
- | | | ||the point of creation |
- | | | ||or the garbage collec- |
- | | | ||tor determines they are |
- || || || ||nor||needed any longer. ||
-
- | -A | 1M |aarrgguummeenntt ssttaacckk ||Theusargumentestackd isto| store one
- | | | ||of the intermediate |
- | | | ||code interpreter's reg- |
- | | | ||isters. The amount |
- | | | ||of space needed on this |
- | | | ||stack is determined en- |
- | | | || |
- | | | ||tirely by the depth in |
- | | | ||which terms are nested |
- | | | ||in the clauses that |
-
- | | | ||constitute the program. |
- | | | ||Overflow is most likely |
- | | | ||when using long strings |
- |________|_______|_______________||in_a_clause.____________|_
-
- Table 2.2: Memory areas
-
-
- 22..1122..11..11 TThhee hheeaapp
-
- With the heap, we refer to the memory area used by mmaalllloocc(()) and
- friends. SWI-Prolog uses the area to store atoms, functors, predicates
- and their clauses, records and other dynamic data. As of SWI-Prolog
- 2.8.5, no limits are imposed on the addresses returned by mmaalllloocc(()) and
- friends.
-
- On some machines, the runtime stacks described above are allocated
- using `sparse allocation'. Virtual space upto the limit is claimed at
- startup and committed and released while the area grows and shrinks.
- On Win32 platform this is realised using VViirrttuuaallAAlllloocc(()) and friends.
- On Unix systems this is realised using mmmmaapp(()), either mapping /dev/zero
- or a temporary file created in /tmp.
-
- As Unix provides no way to reserve part of the address space, this
- process may lead to conflicts. By default, SWI-Prolog computes the
- required virtual address space for the runtime stacks. If available,
- it uses ggeettrrlliimmiitt(()) to determine the top of the virtual space reserved
- for mmaalllloocc(()) usage and locates the stacks in the top of this area. It
- assumes no other mmmmaapp(()) activity such as mapping shared libraries or
- mmmmaapp(()) by foreign modules will use the area reserved for the heap and
- mmaalllloocc(()), mmaalllloocc(()) will grow the heap from low to high addresses and
- will notice the existence of the Prolog stacks.
-
- These assumptions appear to hold. The user may using the -H to
- specify the maximum heap-size. In this case, the Prolog stacks will
- be allocated at the indicated size from the current top of the heap.
- On these system, ssttaattiissttiiccss//[[00,,22]] reports heaplimit and heap. The
- heaplimit value is the distance between the _b_r_e_a_k and the first Prolog
- stack. The heap value is the distance between what Prolog assumes to
- be the base of the heap and the current location of the break.
-
-
- 22..1122..22 OOtthheerr LLiimmiittss
-
- CCllaauusseess Currently the following limitations apply to clauses. The
- arity may not be more than 1024 and the number of variables should
- be less than 65536.
-
- AAttoommss aanndd SSttrriinnggss SWI-Prolog has no limits on the sizes of atoms
- and strings. rreeaadd//11 and its derivatives however normally limit
- the number of newlines in an atom or string to 5 to improve
- error detection and recovery. This can be switched off with
- ssttyyllee__cchheecckk//11.
-
- AAddddrreessss ssppaaccee SWI-Prolog data is packed in a 32-bit word, which
- contains both type and value information. The size of the various
- memory areas is limited to 128 Mb for each of the areas. With some
- redesign, the program area could be split into data that should be
- within this range and the rest of the data, virtually unlimiting
- the program size.
-
- IInntteeggeerrss Integers are 32-bit to the user, but integers upto the value
- of the max_tagged_integer feature are represented more efficiently.
-
- FFllooaattss Floating point numbers are represented as native double
- precision floats, 64 bit IEEE on most machines.
-
-
- 22..1122..33 RReesseerrvveedd NNaammeess
-
- The boot compiler (see -b option) does not support the module system
- (yet). As large parts of the system are written in Prolog itself
- we need some way to avoid name clashes with the user's predicates,
- database keys, etc. Like Edinburgh C-Prolog [Pereira, 1986] all
- predicates, database keys, etc. that should be hidden from the user
- start with a dollar ($) sign (see ssttyyllee__cchheecckk//11).
-
- The compiler uses the special functor $VAR$/1 while analysing the
- clause to compile. Using this functor in a program causes
- unpredictable behaviour of the compiler and resulting program.
-
-
- CChhaapptteerr 33.. BBUUIILLTT--IINN PPRREEDDIICCAATTEESS
-
-
- 33..11 NNoottaattiioonn ooff PPrreeddiiccaattee DDeessccrriippttiioonnss
-
- We have tried to keep the predicate descriptions clear and concise.
- First the predicate name is printed in bold face, followed by the
- arguments in italics. Arguments are preceded by a `+', `-' or `?'
- sign. `+' indicates the argument is input to the predicate, `-'
- denotes output and `?' denotes `either input or output'. Constructs
- like `oopp//33' refer to the predicate `op' with arity `3'.
-
-
- 33..22 CCoonnssuullttiinngg PPrroolloogg SSoouurrccee ffiilleess
-
- SWI-Prolog source files normally have a suffix `.pl'. Specifying the
- suffix is optional. All predicates that handle source files first
- check whether a file with suffix `.pl' exists. If not the plain
- file name is checked for existence. Library files are specified by
- embedding the file name using the functor lliibbrraarryy//11. Thus `foo' refers
- to `foo.pl' or `foo' in the current directory, `library(foo)' refers
- to `foo.pl' or `foo' in one of the library directories specified by
- the dynamic predicate lliibbrraarryy__ddiirreeccttoorryy//11. The user may specify other
- `aliases' than library using the predicate ffiillee__sseeaarrcchh__ppaatthh//22. This
- is strongly encouraged for managing complex applications. See also
- aabbssoolluuttee__ffiillee__nnaammee//[[22,,33]].
-
- SWI-Prolog recognises grammar rules as defined in
- [Clocksin & Melish, 1987]. The user may define additional com-
- pilation of the source file by defining the dynamic predicate
- tteerrmm__eexxppaannssiioonn//22. Transformations by this predicate overrule the
- systems grammar rule transformations. It is not allowed to use
- aasssseerrtt//11, rreettrraacctt//11 or any other database predicate in tteerrmm__eexxppaannssiioonn//22
- other than for local computational purposes.
-
- Directives may be placed anywhere in a source file, invoking any
- predicate. They are executed when encountered. If the directive
- fails, a warning is printed. Directives are specified by :-/1 or ?-/1.
- There is no difference between the two.
-
- SWI-Prolog does not have a separate rreeccoonnssuulltt//11 predicate.
- Reconsulting is implied automatically by the fact that a file is
- consulted which is already loaded.
-
-
- llooaadd__ffiilleess((_+_F_i_l_e_s_, _+_O_p_t_i_o_n_s))
- The predicate llooaadd__ffiilleess//22 is the parent of all the other loading
- predicates. It currently supports a subset of the options of
- Quintus llooaadd__ffiilleess//22. _F_i_l_e_s is either specifies a single, or a
- list of source-files. The specification for a source-file is
- handled aabbssoolluuttee__ffiillee__nnaammee//22. See this predicate for the supported
- expansions. _O_p_t_i_o_n_s is a list of options using the format
-
- _O_p_t_i_o_n_N_a_m_e(_O_p_t_i_o_n_V_a_l_u_e)
-
- The following options are currently supported:
-
- iiff((_C_o_n_d_i_t_i_o_n))
- Load the file only if the specified condition is satisfied.
- The value true loads the file unconditionally, changed loads
- the file if it was not loaded before, or has been modified
- since it was loaded the last time, not_loaded loads the file if
- it was not loaded before.
-
- mmuusstt__bbee__mmoodduullee((_B_o_o_l))
- If true, raise an error if the file is not a module file.
- Used by uussee__mmoodduullee//[[11,,22]].
-
- iimmppoorrttss((_L_i_s_t_O_r_A_l_l))
- If all and the file is a module file, import all public
- predicates. Otherwise import only the named predicates. Each
- predicate is refered to as <_n_a_m_e>/<_a_r_i_t_y>. This option has no
- effect if the file is not a module file.
-
- ssiilleenntt((_B_o_o_l))
- If true, load the file without printing a message. The
- specified value is the default for all files loaded as a
- result of loading the specified files.
-
-
- ccoonnssuulltt((_+_F_i_l_e))
- Read _F_i_l_e as a Prolog source file. _F_i_l_e may be a list of files,
- in which case all members are consulted in turn. _F_i_l_e may start
- with the csh(1) special sequences ~, ~<_u_s_e_r>and $<_v_a_r>. _F_i_l_e may
- also be library(Name), in which case the libraries are searched for
- a file with the specified name. See also lliibbrraarryy__ddiirreeccttoorryy//11 and
- ffiillee__sseeaarrcchh__ppaatthh//22. ccoonnssuulltt//11 may be abbreviated by just typing a
- number of file names in a list. Examples:
-
- ?- consult(load). % consult load or load.pl
- ?- [library(quintus)]. % load Quintus compatibility library
-
- Equivalent to load_files(Files, []).
-
-
- eennssuurree__llooaaddeedd((_+_F_i_l_e))
- If the file is not already loaded, this is equivalent to ccoonnssuulltt//11.
- Otherwise, if the file defines a module, import all public
- predicates. Finally, if the file is already loaded, is not a
- module file and the context module is not the global user module,
- eennssuurree__llooaaddeedd//11 will call ccoonnssuulltt//11.
-
- With the semantics, we hope to get as closely possible to the clear
- semantics without the presence of a module system. Applications
- using modules should consider using uussee__mmoodduullee//[[11,,22]].
-
- Equivalent to load_files(Files, [if(changed)]).
-
-
- rreeqquuiirree((_+_L_i_s_t_O_f_N_a_m_e_A_n_d_A_r_i_t_y))
- Declare that this file/module requires the specified predicates
- to be defined ``with their commonly accepted definition''. This
- predicate originates from the Prolog portability layer for XPCE. It
- is intended to provide a portable mechanism for specifying that
- this module requires the specified predicates.
-
- The implementation normally first verifies whether the predicate is
- already defined. If not, it will search the libraries and load the
- required library.
-
- SWI-Prolog, having autoloading, does nnoott load the library. Instead
- it creates a procedure header for the predicate if this does not
- exist. This will flag the predicate as `undefined'. See also
- cchheecckk//00 and aauuttoollooaadd//00.
-
-
- mmaakkee
- Consult all source files that have been changed since they were
- consulted. It checks _a_l_l loaded source files: files loaded into
- a compiled state using pl -c ... and files loaded using consult
- or one of its derivatives. mmaakkee//00 is normally invoked by the
- eeddiitt//[[00,,11]] and eedd//[[00,,11]] predicates. mmaakkee//00 can be combined with
- the compiler to speed up the development of large packages. In
- this case compile the package using
-
- sun% pl -g make -o my_program -c file ...
-
- If `my_program' is started it will first reconsult all source files
- that have changed since the compilation.
-
-
- lliibbrraarryy__ddiirreeccttoorryy((_?_A_t_o_m))
- Dynamic predicate used to specify library directories. Default
- ./lib, ~/lib/prolog and the system's library (in this order) are
- defined. The user may add library directories using aasssseerrtt//11,
- aasssseerrttaa//11 or remove system defaults using rreettrraacctt//11.
-
-
- ffiillee__sseeaarrcchh__ppaatthh((_+_A_l_i_a_s_, _?_P_a_t_h))
- Dynamic predicate used to specify `path-aliases'. This feature is
- best described using an example. Given the definition
-
- file_search_path(demo, '~/demo').
-
- the file specification demo(myfile) will be expanded to
- ~/demo/myfile. The second argument of ffiillee__sseeaarrcchh__ppaatthh//22may be
- another alias.
-
- Below is the initial definition of the file search path. This
- path implies swi(<_P_a_t_h>) refers to a file in the SWI-Prolog
- home directory. The alias foreign(<_P_a_t_h>) is intended for
- storing shared libraries (.so or .DLL files). See also
- llooaadd__ffoorreeiiggnn__lliibbrraarryy//[[11,,22]].
-
- user:file_search_path(library, X) :-
- library_directory(X).
- user:file_search_path(swi, Home) :-
- feature(home, Home).
- user:file_search_path(foreign, swi(ArchLib)) :-
- feature(arch, Arch),
- concat('lib/', Arch, ArchLib).
- user:file_search_path(foreign, swi(lib)).
-
- The ffiillee__sseeaarrcchh__ppaatthh//22expansion is used by all loading predicates
- as well as by aabbssoolluuttee__ffiillee__nnaammee//22.
-
-
- eexxppaanndd__ffiillee__sseeaarrcchh__ppaatthh((_+_S_p_e_c_, _-_P_a_t_h))
- Unifies _P_a_t_h will all possible expansions of the file name
- specification _S_p_e_c. See also aabbssoolluuttee__ffiillee__nnaammee//33.
-
-
- ssoouurrccee__ffiillee((_?_F_i_l_e))
- Succeeds if _F_i_l_e was loaded using ccoonnssuulltt//11 or eennssuurree__llooaaddeedd//11.
- _F_i_l_e refers to the full path name of the file (see
- eexxppaanndd__ffiillee__nnaammee//22). The predicate ssoouurrccee__ffiillee//11 backtracks over all
- loaded source files.
-
-
- ssoouurrccee__ffiillee((_?_P_r_e_d_, _?_F_i_l_e))
- Is true if the predicate specified by _P_r_e_d was loaded from file
- _F_i_l_e, where _F_i_l_e is an absolute path name (see eexxppaanndd__ffiillee__nnaammee//22).
- Can be used with any instantiation pattern, but the database only
- maintains the source file for each predicate. Predicates declared
- multifile (see mmuullttiiffiillee//11) cannot be found this way.
-
-
- pprroolloogg__llooaadd__ccoonntteexxtt((_?_K_e_y_, _?_V_a_l_u_e))
- Determine loading context. The following keys are defined:
-
- ________________________________________________________________
- |__KKeeyy______________________||DDeessccrriippttiioonn________________________________________________________________________||
- || module |Module into which file is loaded |
- | file |File loaded |
- | stream |Stream identifier (see ccuurrrreenntt__iinnppuutt//11) |
-
- | directory |Directory in which _F_i_l_e lives. |
- | term_position |Position of last term read. Term of the form|
- |_______________|'$stream_position'(0,<_L_i_n_e>,0,0,0)_____________|
-
- Quintus compatibility predicate. See also ssoouurrccee__llooccaattiioonn//22.
-
-
- ssoouurrccee__llooccaattiioonn((_-_F_i_l_e_, _-_L_i_n_e))
- If the last term has been read from a physical file (i.e. not from
- the file user or a string), unify _F_i_l_e with an absolute path to the
- file and _L_i_n_e with the line-number in the file. New code should
- use pprroolloogg__llooaadd__ccoonntteexxtt//22.
-
-
- tteerrmm__eexxppaannssiioonn((_+_T_e_r_m_1_, _-_T_e_r_m_2))
- Dynamic predicate, normally not defined. When defined by the user
- all terms read during consulting that are given to this predicate.
- If the predicate succeeds Prolog will assert _T_e_r_m_2 in the database
- rather then the read term (_T_e_r_m_1). _T_e_r_m_2 may be a term of a the
- form `?- _G_o_a_l' or `:- _G_o_a_l'. _G_o_a_l is then treated as a directive.
- If _T_e_r_m_2 is a list all terms of the list are stored in the database
- or called (for directives). If _T_e_r_m_2 is of the form below, the
- system will assert _C_l_a_u_s_e and record the indicated source-location
- with it.
-
- '$source_location'(<_F_i_l_e>, <_L_i_n_e>):<_C_l_a_u_s_e>
-
- When compiling a module (see chapter 4 and the directive mmoodduullee//22),
- eexxppaanndd__tteerrmm//22 will first try tteerrmm__eexxppaannssiioonn//22in the module being
- compiled to allow for term-expansion rules that are local to
- a module. If there is no local definition, or the local
- definition fails to translate the term, eexxppaanndd__tteerrmm//22 will try
- user:tteerrmm__eexxppaannssiioonn//22. For compatibility with SICStus and Quintus
- Prolog, this feature should not be used. See also eexxppaanndd__tteerrmm//22.
-
-
- eexxppaanndd__tteerrmm((_+_T_e_r_m_1_, _-_T_e_r_m_2))
- This predicate is normally called by the compiler to perform
- preprocessing. First it calls tteerrmm__eexxppaannssiioonn//22. If this predicate
- fails it performs a grammar-rule translation. If this fails it
- returns the first argument.
-
-
- aatt__iinniittiiaalliizzaattiioonn((_+_G_o_a_l))
- Register _G_o_a_l to be ran when the system initialises.
- Initialisation takes place after reloading a .qlf (formerly .wic)
- file as well as after reloading a saved-state. The hooks are run
- in the order they were registered. A warning message is issued if
- _G_o_a_l fails, but execution continues. See also aatt__hhaalltt//11
-
-
- aatt__hhaalltt((_+_G_o_a_l))
- Register _G_o_a_l to be ran when the system halts. The hooks are run
- in the order they were registered. Success or failure executing a
- hook is ignored. These hooks may not call hhaalltt//[[00,,11]].
-
-
- iinniittiiaalliizzaattiioonn((_+_G_o_a_l))
- Call _G_o_a_l and register it using aatt__iinniittiiaalliizzaattiioonn//11. Directives
- that do other things that creating clauses, records, flags or
- setting predicate attributes should normally be written using this
- tag to ensure the initialisation is executed when a saved system
- starts. See also qqssaavvee__pprrooggrraamm//[[11,,22]].
-
-
- ccoommppiilliinngg
- Succeeds if the system is compiling source files with the -c option
- into an intermediate code file. Can be used to perform code
- optimisations in eexxppaanndd__tteerrmm//22 under this condition.
-
-
- pprreepprroocceessssoorr((_-_O_l_d_, _+_N_e_w))
- Read the input file via a Unix process that acts as preprocessor.
- A preprocessor is specified as an atom. The first occurrence of
- the string `%f' is replaced by the name of the file to be loaded.
- The resulting atom is called as a Unix command and the standard
- output of this command is loaded. To use the Unix C preprocessor
- one should define:
-
- ?- preprocessor(Old, '/lib/cpp -C -P %f'), consult(...).
-
- Old = none
-
-
- 33..22..11 QQuuiicckk LLooaadd FFiilleess
-
- The features described in this section should be regarded aallpphhaa.
-
- As of version 2.0.0, SWI-Prolog supports compilation of individual or
- multiple Prolog sourcefiles into `Quick Load Files'. A `Quick Load
- Files' (.qlf file) stores the contents of the file in a precompiled
- format very similar to compiled files created using the -b and -c flags
- (see section 2.7).
-
- These files load considerably faster than sourcefiles and are normally
- more compact. They are machine independent and may thus be loaded
- on any implementation of SWI-Prolog. Note however that clauses are
- stored as virtual machine instructions. Changes to the compiler will
- generally make old compiled files unusable.
-
- Quick Load Files are created using qqccoommppiillee//11. They may be loaded
- explicitly using qqllooaadd//11 or implicitly using ccoonnssuulltt//11 or one of the
- other file-loading predicates described in section 3.2. If consult is
- given the explicit .pl file, it will load the Prolog source. When
- given the .qlf file, it will call qqllooaadd//11 to load the file. When no
- extension is specified, it will load the .qlf file when present and the
- fileextpl file otherwise.
-
-
- qqccoommppiillee((_+_F_i_l_e))
- Takes a single file specification like ccoonnssuulltt//11 (i.e. accepts
- constructs like library(LibFile) and creates a Quick Load File from
- _F_i_l_e. The file-extension of this file is .qlf. The base name of
- the Quick Load File is the same as the input file.
-
- If the file contains `:- consult(+File)' or `:- [+File]'
- statements, the referred files are compiled into the same .qlf
- file. Other directives will be stored in the .qlf file and
- executed in the same fashion as when loading the .pl file.
-
- For tteerrmm__eexxppaannssiioonn//22, the same rules as described in section 2.7
- apply.
-
- Source references (ssoouurrccee__ffiillee//22) in the Quick Load File refer to
- the Prolog source file from which the compiled code originates.
-
-
- qqllooaadd((_+_F_i_l_e))
- Loads the `Quick Load File'. It has the same semantics as
- ccoonnssuulltt//11 for a normal sourcefile. Equivalent to consult(File) iff
- _F_i_l_e refers to a `Quick Load File'.
-
-
- 33..33 LLiissttiinngg PPrreeddiiccaatteess aanndd EEddiittoorr IInntteerrffaaccee
-
- SWI-Prolog offers an interface to the Unix vi editor and the GNU Emacs
- invocations emacs and emacsclient. Which editor is used is determined
- by the Unix environment variable EDITOR, which should hold the full
- pathname of the editor. If this variable is not defined, vi is used.
-
- After the user quits the editor, mmaakkee//00 is invoked to reload all
- modified source files using ccoonnssuulltt//11. If the editor can be quit such
- that an exit status non-equal to 0 is returned mmaakkee//00 will not be
- invoked. _t_o_p can do this by typing control-C, _v_i cannot do this.
-
- A predicate specification is either a term with the same functor and
- arity as the predicate wanted, a term of the form _F_u_n_c_t_o_r/_A_r_i_t_y or
- a single atom. In the latter case the database is searched for a
- predicate of this name and arbitrary arity (see ccuurrrreenntt__pprreeddiiccaattee//22).
- When more than one such predicate exists the system will prompt
- for confirmation on each of the matched predicates. Predicates
- specifications are given to the `Do What I Mean' system (see
- ddwwiimm__pprreeddiiccaattee//22) if the requested predicate does not exist.
-
-
- eedd((_+_P_r_e_d))
- Invoke the user's preferred editor on the source file of _P_r_e_d,
- providing a search specification which searches for the predicate
- at the start of a line.
-
-
- eedd
- Invoke eedd//11 on the predicate last edited using eedd//11. Asks the user
- to confirm before starting the editor.
-
-
- eeddiitt((_+_F_i_l_e))
- Invoke the user's preferred editor on _F_i_l_e. _F_i_l_e is a file
- specification as for ccoonnssuulltt//11 (but not a list). Note that the
- file should exist.
-
-
- eeddiitt
- Invoke eeddiitt//11 on the file last edited using eeddiitt//11. Asks the user
- to confirm before starting the editor.
-
-
- lliissttiinngg((_+_P_r_e_d))
- List specified predicates (when an atom is given all predicates
- with this name will be listed). The listing is produced on the
- basis of the internal representation, thus loosing user's layout
- and variable name information. See also ppoorrttrraayy__ccllaauussee//11.
-
-
- lliissttiinngg
- List all predicates of the database using lliissttiinngg//11.
-
-
- ppoorrttrraayy__ccllaauussee((_+_C_l_a_u_s_e))
- Pretty print a clause as good as we can. A clause should be
- specified as a term `<_H_e_a_d> :- <_B_o_d_y>' (put brackets around it to
- avoid operator precedence problems). Facts are represented as
- `<_H_e_a_d> :- true'.
-
-
- eeddiitt__ssoouurrccee((_+_S_p_e_c))
- A hook that may be defined in the module user to specify how the
- predicates eedd//11 and eeddiitt//11 call the editor. If eedd//11 is invoking
- this hook, _S_p_e_c is a term of the format
-
- File:LineNo:Name/Arity
-
- Where _F_i_l_e and _L_i_n_e_N_o represents the location of the predicate
- remembered by Prolog, and _N_a_m_e and _A_r_i_t_y specify the predicate. If
- invoked by eeddiitt//11, _S_p_e_c is an atom denoting the name of the file to
- be edited. This hook is defined by the library library(swi_prolog)
- distributed with the XPCE package for using XPCE to edit Prolog
- files.
-
-
- 33..44 VVeerriiffyy TTyyppee ooff aa TTeerrmm
-
-
- vvaarr((_+_T_e_r_m))
- Succeeds if _T_e_r_m currently is a free variable.
-
-
- nnoonnvvaarr((_+_T_e_r_m))
- Succeeds if _T_e_r_m currently is not a free variable.
-
-
- iinntteeggeerr((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to an integer.
-
-
- ffllooaatt((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to a floating point number.
-
-
- nnuummbbeerr((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to an integer or a floating point number.
-
-
- aattoomm((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to an atom.
-
-
- ssttrriinngg((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to a string.
-
-
- aattoommiicc((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to an atom, string, integer or floating
- point number.
-
-
- ccoommppoouunndd((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to a compound term. See also ffuunnccttoorr//33
- and =../2.
-
-
- ggrroouunndd((_+_T_e_r_m))
- Succeeds if _T_e_r_m holds no free variables.
-
-
- 33..55 CCoommppaarriissoonn aanndd UUnniiffiiccaattiioonn oorr TTeerrmmss
-
-
- 33..55..11 SSttaannddaarrdd OOrrddeerr ooff TTeerrmmss
-
- Comparison and unification of arbitrary terms. Terms are ordered in
- the so called ``standard order''. This order is defined as follows:
-
- 1. _V_a_r_i_a_b_l_e_s <_A_t_o_m_s <_S_t_r_i_n_g_s <_N_u_m_b_e_r_s <_T_e_r_m_s
-
- 2. _O_l_d _V_a_r_i_a_b_l_e <_N_e_w _V_a_r_i_a_b_l_e
-
- 3. _A_t_o_m_s are compared alphabetically.
-
- 4. _S_t_r_i_n_g_s are compared alphabetically.
-
- 5. _N_u_m_b_e_r_s are compared by value. Integers and floats are treated
- identically.
-
- 6. _T_e_r_m_s are first checked on their functor (alphabetically), then on
- their arity and finally recursively on their arguments, leftmost
- argument first.
-
-
- _+_T_e_r_m_1 == _+_T_e_r_m_2
- Succeeds if _T_e_r_m_1 is equivalent to _T_e_r_m_2. A variable is only
- identical to a sharing variable.
-
-
- _+_T_e_r_m_1 \== _+_T_e_r_m_2
- Equivalent to \+Term1 == Term2.
-
-
- _+_T_e_r_m_1 = _+_T_e_r_m_2
- Unify _T_e_r_m_1 with _T_e_r_m_2. Succeeds if the unification succeeds.
-
-
- _+_T_e_r_m_1 \= _+_T_e_r_m_2
- Equivalent to \+Term1 = Term2.
-
-
- _+_T_e_r_m_1 =@= _+_T_e_r_m_2
- Succeeds if _T_e_r_m_1 is `structurally equal' to _T_e_r_m_2. Structural
- equivalence is weaker than equivalence (==//22), but stronger than
- unification (=//22). Two terms are structurally equal if their tree
- representation is identical and they have the same `pattern' of
- variables. Examples:
-
- a =@= A false
- A =@= B true
- x(A,A) =@= x(B,C) false
- x(A,A) =@= x(B,B) true
- x(A,B) =@= x(C,D) true
-
-
- _+_T_e_r_m_1 \=@= _+_T_e_r_m_2
- Equivalent to `\+Term1 =@= Term2'.
-
-
- _+_T_e_r_m_1 @< _+_T_e_r_m_2
- Succeeds if _T_e_r_m_1 is before _T_e_r_m_2 in the standard order of terms.
-
-
- _+_T_e_r_m_1 @=< _+_T_e_r_m_2
- Succeeds if both terms are equal (==//22) or _T_e_r_m_1 is before _T_e_r_m_2 in
- the standard order of terms.
-
-
- _+_T_e_r_m_1 @> _+_T_e_r_m_2
- Succeeds if _T_e_r_m_1 is after _T_e_r_m_2 in the standard order of terms.
-
-
- _+_T_e_r_m_1 @>= _+_T_e_r_m_2
- Succeeds if both terms are equal (==//22) or _T_e_r_m_1 is after _T_e_r_m_2 in
- the standard order of terms.
-
-
- ccoommppaarree((_?_O_r_d_e_r_, _+_T_e_r_m_1_, _+_T_e_r_m_2))
- Determine or test the _O_r_d_e_r between two terms in the standard order
- of terms. _O_r_d_e_r is one of <, > or =, with the obvious meaning.
-
-
- 33..66 CCoonnttrrooll PPrreeddiiccaatteess
-
- The predicates of this section implement control structures. Normally
- these constructs are translated into virtual machine instructions by
- the compiler. It is still necessary to implement these constructs as
- true predicates to support meta-calls, as demonstrated in the example
- below. The predicate finds all currently defined atoms of 1 character
- long. Note that the cut has no effect when called via one of these
- predicates (see !/0).
-
- one_character_atoms(As) :-
- findall(A, (current_atom(A), atom_length(A, 1)), As).
-
-
- ffaaiill
- Always fail. The predicate ffaaiill//00 is translated into a single
- virtual machine instruction.
-
-
- ttrruuee
- Always succeed. The predicate ttrruuee//00 is translated into a single
- virtual machine instruction.
-
-
- rreeppeeaatt
- Always succeed, provide an infinite number of choice points.
-
-
- !
- Cut. Discard choice points of parent frame and frames created
- after the parent frame. Note that the control structures ;//22,
- |//22, ->//22 and \+//11 are normally handled by the compiler and do
- not create a frame, which implies the cut operates through these
- predicates. Some examples are given below. Note the difference
- between t3/1 and t4/1. Also note the effect of ccaallll//11 in t5/0. As
- the argument of ccaallll//11 is evaluated by predicates rather than the
- compiler the cut has no effect.
-
- t1 :- (a, !, fail ; b). % cuts a/0 and t1/0
- t2 :- (a -> b, ! ; c). % cuts b/0 and t2/0
- t3(G) :- a, G, fail. % if `G = !' cuts a/0 and t1/1
- t4(G) :- a, call(G), fail. % if `G = !' cut has no effect
- t5 :- call((a, !, fail ; b)). % Cut has no effect
-
- t6 :- \+(a, !, fail ; b). % cuts a/0 and t6/0
-
-
- _+_G_o_a_l_1 , _+_G_o_a_l_2
- Conjunction. Succeeds if both `Goal1' and `Goal2' can be proved.
- It is defined as (this definition does not lead to a loop as the
- second comma is handled by the compiler):
-
- Goal1, Goal2 :- Goal1, Goal2.
-
-
- _+_G_o_a_l_1 ; _+_G_o_a_l_2
- The `or' predicate is defined as:
-
- Goal1 ; _Goal2 :- Goal1.
- _Goal1 ; Goal2 :- Goal2.
-
-
- _+_G_o_a_l_1 | _+_G_o_a_l_2
- Equivalent to ;//22. Retained for compatibility only. New code
- should use ;//22. Still nice though for grammar rules.
-
-
- _+_C_o_n_d_i_t_i_o_n -> _+_A_c_t_i_o_n
- If-then and If-Then-Else. The ->//22 construct commits to the
- choices made at its left-hand side, destroying choice-points
- created inside the clause (by ;//22), or by goals called by this
- clause. Unlike !//00, the choicepoint of the predicate as a whole
- (due to multiple clauses) is nnoott destroyed. The combination ;//22
- and ->//22 is defines as:
-
- If -> Then; _Else :- If, !, Then.
- If -> _Then; Else :- !, Else.
- If -> Then :- If, !, Then.
-
- Note that the operator precedence relation between ; and
- -> ensure If -> Then ; Else is actually a term of the form
- ;(->(If, Then), Else). The first two clauses belong to the
- definition of ;//22), while only the last defines ->//22 .
-
-
- _+_C_o_n_d_i_t_i_o_n *-> _+_A_c_t_i_o_n _; _+_E_l_s_e
- This construct implements the so-called `soft-cut'. The control
- is defined as follows: If _C_o_n_d_i_t_i_o_n succeeds at least once, the
- semantics is the same as (_C_o_n_d_i_t_i_o_n, _A_c_t_i_o_n). If _C_o_n_d_i_t_i_o_n does
- not succeed, the semantics is that of (_C_o_n_d_i_t_i_o_n, _E_l_s_e). In other
- words, If _C_o_n_d_i_t_i_o_n succeeds at least once, simply behave as the
- conjunction of _C_o_n_d_i_t_i_o_n and _A_c_t_i_o_n, otherwise execute _E_l_s_e.
-
-
- \+ _+_G_o_a_l
- Succeeds if `Goal' cannot be proven (mnemonic: + refers to
- _p_r_o_v_a_b_l_e and the backslash (\) is normally used to indicate
- negation).
-
-
- 33..77 MMeettaa--CCaallll PPrreeddiiccaatteess
-
- Meta call predicates are used to call terms constructed at run time.
- The basic meta-call mechanism offered by SWI-Prolog is to use variables
- as a subclause (which should of course be bound to a valid goal at
- runtime). A meta-call is slower than a normal call as it involves
- actually searching the database at runtime for the predicate, while for
- normal calls this search is done at compile time.
-
-
- ccaallll((_+_G_o_a_l))
- Invoke _G_o_a_l as a goal. Note that clauses may have variables as
- subclauses, which is identical to ccaallll//11, except when the argument
- is bound to the cut. See !//00.
-
-
- ccaallll((_+_G_o_a_l_, _+_E_x_t_r_a_A_r_g_1_, _._._.))
- Append _E_x_t_r_a_A_r_g_1_, _E_x_t_r_a_A_r_g_2_, _._._. to the argument list of _G_o_a_l
- and call the result. For example, call(plus(1), 2, X) will call
- pplluuss//33, binding _X to 3.
-
- The call/[2..] construct is handled by the compiler, which implies
- that redefinition as a predicate has no effect. The predicates
- ccaallll//[[22--66]] are defined as true predicates, so they can be handled
- by interpreted code.
-
-
- aappppllyy((_+_T_e_r_m_, _+_L_i_s_t))
- Append the members of _L_i_s_t to the arguments of _T_e_r_m and call the
- resulting term. For example: apply(plus(1), [2, X]) will call
- plus(1, 2, X). aappppllyy//22 is incorporated in the virtual machine of
- SWI-Prolog. This implies that the overhead can be compared to the
- overhead of ccaallll//11. New code should use call/[2..] if the length
- of _L_i_s_t is fixed, which is more widely supported and faster because
- there is no need to build and examine the argument list.
-
-
- nnoott((_+_G_o_a_l))
- Succeeds when _G_o_a_l cannot be proven. Retained for compatibility
- only. New code should use \+//11.
-
-
- oonnccee((_+_G_o_a_l))
- Defined as:
-
- once(Goal) :-
- Goal, !.
-
- oonnccee//11 can in many cases be replaced with ->//22. The only
- difference is how the cut behaves (see !/0). The following two
- clauses are identical:
-
- 1) a :- once((b, c)), d.
- 2) a :- b, c -> d.
-
-
- iiggnnoorree((_+_G_o_a_l))
- Calls _G_o_a_l as oonnccee//11, but succeeds, regardless of whether _G_o_a_l
- succeeded or not. Defined as:
-
- ignore(Goal) :-
- Goal, !.
- ignore(_).
-
-
- ccaallll__wwiitthh__ddeepptthh__lliimmiitt((_+_G_o_a_l_, _+_L_i_m_i_t_, _-_R_e_s_u_l_t))
- If _G_o_a_l can be proven without recursion deeper than _L_i_m_i_t levels,
- ccaallll__wwiitthh__ddeepptthh__lliimmiitt//33 succeeds, binding _R_e_s_u_l_t to the deepest
- recursion level used during the proof. Otherwise, _R_e_s_u_l_t is
- unified with depth_limit_exceeded if the limit was exceeded during
- the proof, or the entire predicate fails if _G_o_a_l fails without
- exceeding _L_i_m_i_t.
-
- The depth-limit is guarded by the internal machinery. This differ
- from the depth computed based on a theoretical model. For
- example, ttrruuee//00 is translated into an inlined virtual machine
- instruction. Also, rreeppeeaatt//00 is not implemented as below, but as a
- non-deterministic foreign predicate.
-
- repeat.
- repeat :-
- repeat.
-
- As a result, ccaallll__wwiitthh__ddeepptthh__lliimmiitt//33may still loop inifitly on
- programs that should theoretically finish in finite time. This
- problem can be cured by using Prolog equivalents to such built-in
- predicates.
-
- This predicate may be used for theorem-provers to realise
- techniques like _i_t_e_r_r_a_t_i_v_e _d_e_e_p_e_n_i_n_g. It was implemented after
- discussion with Steve Moyle smoyle@ermine.ox.ac.uk.
-
-
- 33..88 IISSOO ccoommpplliiaanntt EExxcceeppttiioonn hhaannddlliinngg
-
- SWI-Prolog defines the predicates ccaattcchh//33 and tthhrrooww//11 for ISO compliant
- raising and catching of exceptions. In the current implementation
- (2.9.0), only part of the built-in predicates generate exceptions. In
- general, exceptions are implemented for I/O and arithmetic.
-
-
- ccaattcchh((_:_G_o_a_l_, _+_C_a_t_c_h_e_r_, _:_R_e_c_o_v_e_r))
- Behaves as ccaallll//11 if no exception is raised when executing _G_o_a_l.
- If a exception is raised using tthhrrooww//11 while _G_o_a_l executes, and
- the _G_o_a_l is the innermost goal for which _C_a_t_c_h_e_r unifies with the
- argument of tthhrrooww//11, all choicepoints generated by _G_o_a_l are cut,
- and _R_e_c_o_v_e_r is called as in ccaallll//11.
-
- The overhead of calling a goal through ccaattcchh//33 is very comparable
- to ccaallll//11. Recovery from an exception has a similar overhead.
-
-
- tthhrrooww((_+_E_x_c_e_p_t_i_o_n))
- Raise an exception. The system will look for the innermost ccaattcchh//33
- ancestor for which _E_x_c_e_p_t_i_o_n unifies with the _C_a_t_c_h_e_r argument of
- the ccaattcchh//33 call. See ccaattcchh//33 for details.
-
- If there is no ccaattcchh//33 willing to catch the error in the current
- Prolog context, the toplevel (pprroolloogg//00) catches the error and
- prints a warning message. If an exception was raised in a
- callback from C (see chapter 5), PPLL__nneexxtt__ssoolluuttiioonn(())will fail and
- the exception context can be retrieved using PPLL__eexxcceeppttiioonn(()).
-
-
- 33..88..11 DDeebbuuggggiinngg aanndd eexxcceeppttiioonnss
-
- Before the introduction of exceptions in SWI-Prolog a runtime error was
- handled by printing an error message, after which the predicate failed.
- If the feature (see ffeeaattuurree//22) debug_on_error was in effect (default),
- the tracer was switched on. The combination of the error message and
- trace information is generally sufficient to locate the error.
-
- With exception handling, things are different. A programmer may wish
- to trap an exception using ccaattcchh//33 to avoid it reaching the user. If
- the exception is not handled by user-code, the interactive toplevel
- will trap it to prevent termination.
-
- If we do not take special precautions, the context information
- associated with an unexpected exception (i.e. a programming error) is
- lost. Therefore, if an exception is raised, which is not caught using
- ccaattcchh//33 and the toplevel is running, the error will be printed, and the
- system will enter trace mode.
-
- If the system is in an non-interactive callback from foreign code and
- there is no ccaattcchh//33 active in the current context, it cannot determine
- whether or not the exception will be caught by the external routine
- calling Prolog. It will then base its behaviour on the feature
- debug_on_error:
-
- o _f_e_a_t_u_r_e_(_d_e_b_u_g___o_n___e_r_r_o_r_, _f_a_l_s_e_)
- The exception does not trap the debugger and is returned to the
- foreign routine calling Prolog, where it can be accessed using
- PPLL__eexxcceeppttiioonn(()). This is the default.
-
- o _f_e_a_t_u_r_e_(_d_e_b_u_g___o_n___e_r_r_o_r_, _t_r_u_e_)
- If the exception is not caught by Prolog in the current context, it
- will trap the tracer to help analysing the context of the error.
-
- While looking for the context in which an exception takes place, it is
- adviced to switch on debug mode using the predicate ddeebbuugg//00.
-
-
- 33..88..22 TThhee eexxcceeppttiioonn tteerrmm
-
- Builtin predicates generates exceptions using a term error(_F_o_r_m_a_l_,
- _C_o_n_t_e_x_t). The first argument is the `formal' description of the
- error, specifying the class and generic defined context information.
- When applicable, the ISO error-term definition is used. The second
- part describes some additional context to help the programmer while
- debugging. In its most generic form this is a term of the form
- context(_N_a_m_e_/_A_r_i_t_y_, _M_e_s_s_a_g_e), where _N_a_m_e/_A_r_i_t_y describes the built-in
- predicate that raised the error, and _M_e_s_s_a_g_e provides an additional
- description of the error. Any part of this structure may be a variable
- if no information was present.
-
-
- 33..88..33 PPrriinnttiinngg aa mmeessssaaggee ffrroomm aann eexxcceeppttiioonn
-
- The predicate pprriinntt__mmeessssaaggee//22 may be used to print an exception term in
- a human readable format:
-
-
- pprriinntt__mmeessssaaggee((_+_K_i_n_d_, _+_T_e_r_m))
- This predicate is modelled after the Quintus predicate with the
- same name, though its current implementation is incomplete. It
- is used only for printing messages from exceptions from built-in
- predicates. _K_i_n_d is one of informational, warning, consterror,
- help or silent. Currently only error is defined. _T_e_r_m is an
- eerrrroorr((_2)) term described in section 3.8.2. A human-readable message
- is printed to the stream user_error.
-
- This predicate first obtains the `human translation' of _T_e_r_m and
- then calls mmeessssaaggee__hhooookk//33. If this fails the message is printed to
- the stream user_error.
-
- The pprriinntt__mmeessssaaggee//22 predicate and its rules are in the file
- <_p_l_h_o_m_e>/boot/messages.pl, which may be inspected for more
- information on the error messages and related error terms.
-
-
- mmeessssaaggee__hhooookk((_+_T_e_r_m_, _+_K_i_n_d_, _+_M_e_s_s_a_g_e))
- Hook predicate that may be define in the module user to intercept
- messages from pprriinntt__mmeessssaaggee//22. _T_e_r_m and _K_i_n_d are the same as
- passed to pprriinntt__mmeessssaaggee//22. _M_e_s_s_a_g_e is a string containing the
- human readable translation of the message. If this predicate
- succeeds, pprriinntt__mmeessssaaggee//22 considers the message printed.
-
- This predicate should be defined dynamic and multifile to allow
- other modules defining clauses for it too.
-
-
- 33..99 AAddvvaanncceedd ccoonnttrrooll--ssttrruuccttuurreess:: bblloocckkss
-
- The predicates of this section form a tightly related set for realising
- premature successful or failing exits from a _b_l_o_c_k. These predicates
- are first of all useful for error-recovery. They were primarily
- implemented for compatibility reasons.
-
-
- bblloocckk((_+_L_a_b_e_l_, _+_G_o_a_l_, _-_E_x_i_t_V_a_l_u_e))
- Execute _G_o_a_l in a _b_l_o_c_k. _L_a_b_e_l is the name of the block. _L_a_b_e_l
- is normally an atom, but the system imposes no type constraints
- and may even be a variable. _E_x_i_t_V_a_l_u_e is normally unified to the
- second argument of an eexxiitt//22 call invoked by _G_o_a_l.
-
-
- eexxiitt((_+_L_a_b_e_l_, _+_V_a_l_u_e))
- Calling eexxiitt//22 makes the innermost _b_l_o_c_k which _L_a_b_e_l unifies exit.
- The block's _E_x_i_t_V_a_l_u_e is unified with _V_a_l_u_e. If this unification
- fails the block fails.
-
-
- ffaaiill((_+_L_a_b_e_l))
- Calling ffaaiill//11 makes the innermost _b_l_o_c_k which _L_a_b_e_l unifies fail
- immediately. Implemented as
-
- fail(Label) :- !(Label), fail.
-
-
- !((_+_L_a_b_e_l))
- Cut all choice-points created since the entry of the innermost
- _b_l_o_c_k which _L_a_b_e_l unifies.
-
- The example below illustrate these constructs to immediately report a
- syntax-error from a `deep-down' procedure to the outside world without
- passing it as an argument `all-over-the-place'.
-
- parse(RuleSet, InputList, Rest) :-
- block(syntaxerror, phrase(RuleSet, InputList, Rest), Error),
- ( var(Error)
- -> true
- ; format('Syntax-error: ~w~n', Error),
- fail
- ).
-
- integer(N) -->
- digit(D1), !, digits(Ds),
- { name(N, [D1|Ds]) }.
-
- digits([D|R]) --> digit(D), digits(R).
- digits(_) --> letter(_), !, { exit(syntaxerror, 'Illegal number') }.
- digits([]) --> [].
-
- digit(D, [D|R], R) :- between(0'0, 0'9, D).
- letter(D, [D|R], R) :- between(0'a, 0'z, D).
-
-
- 33..1100 GGrraammmmaarr rruullee iinntteerrffaaccee ((pphhrraassee))
-
- The predicates below may be called to activate a grammar-rule set:
-
-
- pphhrraassee((_+_R_u_l_e_S_e_t_, _+_I_n_p_u_t_L_i_s_t))
- Equivalent to phrase(RuleSet, InputList, []).
-
-
- pphhrraassee((_+_R_u_l_e_S_e_t_, _+_I_n_p_u_t_L_i_s_t_, _-_R_e_s_t))
- Activate the rule-set with given name. `InputList' is the list of
- tokens to parse, `Rest' is unified with the remaining tokens if the
- sentence is parsed correctly.
-
-
- 33..1111 DDaattaabbaassee
-
- SWI-Prolog offers three different database mechanisms. The first one
- is the common assert/retract mechanism for manipulating the clause
- database. As facts and clauses asserted using aasssseerrtt//11 or one of
- its derivatives become part of the program these predicates compile
- the term given to them. rreettrraacctt//11 and rreettrraaccttaallll//11 have to unify a
- term and therefore have to decompile the program. For these reasons
- the assert/retract mechanism is expensive. On the other hand, once
- compiled, queries to the database are faster than querying the recorded
- database discussed below. See also ddyynnaammiicc//11.
-
- The second way of storing arbitrary terms in the database is using the
- ``recorded database''. In this database terms are associated with a
- _k_e_y. A key can be an atom, integer or term. In the last case only the
- functor and arity determine the key. Each key has a chain of terms
- associated with it. New terms can be added either at the head or at
- the tail of this chain. This mechanism is considerably faster than
- the assert/retract mechanism as terms are not compiled, but just copied
- into the heap.
-
- The third mechanism is a special purpose one. It associates an integer
- or atom with a key, which is an atom, integer or term. Each key
- can only have one atom or integer associated with it. It again is
- considerably faster than the mechanisms described above, but can only
- be used to store simple status information like counters, etc.
-
-
- aabboolliisshh((_:_P_r_e_d_i_c_a_t_e_I_n_d_i_c_a_t_o_r))
- Removes all clauses of a predicate with functor _F_u_n_c_t_o_r and arity
- _A_r_i_t_y from the database. Unlike version 1.2, all predicate
- attributes (dynamic, multifile, index, etc.) are reset to their
- defaults. Abolishing an imported predicate only removes the import
- link; the predicate will keep its old definition in its definition
- module. For `cleanup' of the dynamic database, one should use
- rreettrraaccttaallll//11 rather than aabboolliisshh//22.
-
-
- aabboolliisshh((_+_N_a_m_e_, _+_A_r_i_t_y))
- Same as abolish(Name/Arity). The predicate aabboolliisshh//22 conforms to
- the Edinburgh standard, while aabboolliisshh//11 is ISO compliant.
-
-
- rreeddeeffiinnee__ssyysstteemm__pprreeddiiccaattee((_+_H_e_a_d))
- This directive may be used both in module user and in normal
- modules to redefine any system predicate. If the system definition
- is redefined in module user, the new definition is the default
- definition for all sub-modules. Otherwise the redefinition is
- local to the module. The system definition remains in the module
- system.
-
- Redefining system predicate facilitates the definition of
- compatibility packages. Use in other context is discouraged.
-
-
- rreettrraacctt((_+_T_e_r_m))
- When _T_e_r_m is an atom or a term it is unified with the first
- unifying fact or clause in the database. The fact or clause is
- removed from the database.
-
-
- rreettrraaccttaallll((_+_H_e_a_d))
- All facts or clauses in the database for which the _h_e_a_d unifies
- with _H_e_a_d are removed.
-
-
- aasssseerrtt((_+_T_e_r_m))
- Assert a fact or clause in the database. _T_e_r_m is asserted as the
- last fact or clause of the corresponding predicate.
-
-
- aasssseerrttaa((_+_T_e_r_m))
- Equivalent to aasssseerrtt//11, but _T_e_r_m is asserted as first clause or
- fact of the predicate.
-
-
- aasssseerrttzz((_+_T_e_r_m))
- Equivalent to aasssseerrtt//11.
-
-
- aasssseerrtt((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
- Equivalent to aasssseerrtt//11, but _R_e_f_e_r_e_n_c_e is unified with a unique
- reference to the asserted clause. This key can later be used with
- ccllaauussee//33 or eerraassee//11.
-
-
- aasssseerrttaa((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
- Equivalent to aasssseerrtt//22, but _T_e_r_m is asserted as first clause or
- fact of the predicate.
-
-
- aasssseerrttzz((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
- Equivalent to aasssseerrtt//22.
-
-
- rreeccoorrddaa((_+_K_e_y_, _+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
- Assert _T_e_r_m in the recorded database under key _K_e_y. _K_e_y is
- an integer, atom or term. _R_e_f_e_r_e_n_c_e is unified with a unique
- reference to the record (see eerraassee//11).
-
-
- rreeccoorrddaa((_+_K_e_y_, _+_T_e_r_m))
- Equivalent to recorda(Key, Value, _).
-
-
- rreeccoorrddzz((_+_K_e_y_, _+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
- Equivalent to rreeccoorrddaa//33, but puts the _T_e_r_m at the tail of the terms
- recorded under _K_e_y.
-
-
- rreeccoorrddzz((_+_K_e_y_, _+_T_e_r_m))
- Equivalent to recordz(Key, Value, _).
-
-
- rreeccoorrddeedd((_+_K_e_y_, _-_V_a_l_u_e_, _-_R_e_f_e_r_e_n_c_e))
- Unify _V_a_l_u_e with the first term recorded under _K_e_y which does
- unify. _R_e_f_e_r_e_n_c_e is unified with the memory location of the
- record.
-
-
- rreeccoorrddeedd((_+_K_e_y_, _-_V_a_l_u_e))
- Equivalent to recorded(Key, Value, _).
-
-
- eerraassee((_+_R_e_f_e_r_e_n_c_e))
- Erase a record or clause from the database. _R_e_f_e_r_e_n_c_e is an
- integer returned by rreeccoorrddaa//33 or rreeccoorrddeedd//33, ccllaauussee//33, aasssseerrtt//22,
- aasssseerrttaa//22 or aasssseerrttzz//22. Other integers might conflict with the
- internal consistency of the system. Erase can only be called once
- on a record or clause. A second call also might conflict with the
- internal consistency of the system.
-
-
- ffllaagg((_+_K_e_y_, _-_O_l_d_, _+_N_e_w))
- _K_e_y is an atom, integer or term. Unify _O_l_d with the old value
- associated with _K_e_y. If the key is used for the first time _O_l_d is
- unified with the integer 0. Then store the value of _N_e_w, which
- should be an integer, float, atom or arithmetic expression, under
- _K_e_y. ffllaagg//33 is a very fast mechanism for storing simple facts in
- the database. Example:
-
- :- module_transparent succeeds_n_times/2.
-
- succeeds_n_times(Goal, Times) :-
- flag(succeeds_n_times, Old, 0),
- Goal,
- flag(succeeds_n_times, N, N+1),
- fail ; flag(succeeds_n_times, Times, Old).
-
-
- 33..1111..11 IInnddeexxiinngg ddaattaabbaasseess
-
- By default, SWI-Prolog, as most other implementations, indexes
- predicates on their first argument. SWI-Prolog allows indexing on
- other and multiple arguments using the declaration iinnddeexx//11.
-
- For advanced database indexing, it defines hhaasshh__tteerrmm//22:
-
-
- hhaasshh__tteerrmm((_+_T_e_r_m_, _-_H_a_s_h_K_e_y))
- If _T_e_r_m is a ground term (see ggrroouunndd//11), _H_a_s_h_K_e_y is unified with a
- positive integer value that may be used as a hash-key to the value.
- If _T_e_r_m is not ground, the predicate succeeds immediately, leaving
- _H_a_s_h_K_e_y an unbound variable.
-
- This predicate may be used to build hash-tables as well as to
- exploit argument-indexing to find complex terms more quickly.
-
- The hash-key does not rely on temporary information like addresses
- of atoms and may be assumed constant over different invocations of
- SWI-Prolog.
-
-
- 33..1122 DDeeccllaarriinngg PPrrooppeerrttiieess ooff PPrreeddiiccaatteess
-
- This section describes directives which manipulate attributes of
- predicate definitions. The functors ddyynnaammiicc//11, mmuullttiiffiillee//11 and
- ddiissccoonnttiigguuoouuss//11 are operators of priority 1150 (see oopp//33), which
- implies the list of predicates they involve can just be a comma
- separated list:
-
- :- dynamic
- foo/0,
- baz/2.
-
- On SWI-Prolog all these directives are just predicates. This implies
- they can also be called by a program. Do not rely on this feature if
- you want to maintain portability to other Prolog implementations.
-
-
- ddyynnaammiicc _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._.
- Informs the interpreter that the definition of the predicate(s)
- may change during execution (using aasssseerrtt//11 and/or rreettrraacctt//11).
- Currently ddyynnaammiicc//11 only stops the interpreter from complaining
- about undefined predicates (see uunnkknnoowwnn//22). Future releases
- might prohibit aasssseerrtt//11 and rreettrraacctt//11 for not-dynamic declared
- procedures.
-
-
- mmuullttiiffiillee _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._.
- Informs the system that the specified predicate(s) may be defined
- over more than one file. This stops ccoonnssuulltt//11 from redefining a
- predicate when a new definition is found.
-
-
- ddiissccoonnttiigguuoouuss _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._.
- Informs the system that the clauses of the specified predicate(s)
- might not be together in the source file. See also ssttyyllee__cchheecckk//11.
-
-
- iinnddeexx((_+_H_e_a_d))
- Index the clauses of the predicate with the same name and arity
- as _H_e_a_d on the specified arguments. _H_e_a_d is a term of which
- all arguments are either `1' (denoting `index this argument')
- or `0' (denoting `do not index this argument'). Indexing has
- no implications for the semantics of a predicate, only on its
- performance. If indexing is enabled on a predicate a special
- purpose algorithm is used to select candidate clauses based on
- the actual arguments of the goal. This algorithm checks whether
- indexed arguments might unify in the clause head. Only atoms,
- integers and functors (e.g. name and arity of a term) are
- considered. Indexing is very useful for predicates with many
- clauses representing facts.
-
- Due to the representation technique used at most 4 arguments can be
- indexed. All indexed arguments should be in the first 32 arguments
- of the predicate. If more than 4 arguments are specified for
- indexing only the first 4 will be accepted. Arguments above 32 are
- ignored for indexing.
-
- By default all predicates with <_a_r_i_t_y> 1 are indexed on their
- first argument. It is possible to redefine indexing on predicates
- that already have clauses attached to them. This will initiate a
- scan through the predicates clause list to update the index summary
- information stored with each clause.
-
- If---for example---one wants to represents sub-types using a fact
- list `sub_type(Sub, Super)' that should be used both to determine
- sub- and super types one should declare sub_type/2 as follows:
-
- :- index(sub_type(1, 1)).
-
- sub_type(horse, animal).
- ...
- ...
-
-
- 33..1133 EExxaammiinniinngg tthhee PPrrooggrraamm
-
-
- ccuurrrreenntt__aattoomm((_-_A_t_o_m))
- Successively unifies _A_t_o_m with all atoms known to the system. Note
- that ccuurrrreenntt__aattoomm//11always succeeds if _A_t_o_m is instantiated to an
- atom.
-
-
- ccuurrrreenntt__ffuunnccttoorr((_?_N_a_m_e_, _?_A_r_i_t_y))
- Successively unifies _N_a_m_e with the name and _A_r_i_t_y with the arity of
- functors known to the system.
-
-
- ccuurrrreenntt__ffllaagg((_-_F_l_a_g_K_e_y))
- Successively unifies _F_l_a_g_K_e_y with all keys used for flags (see
- ffllaagg//33).
-
-
- ccuurrrreenntt__kkeeyy((_-_K_e_y))
- Successively unifies _K_e_y with all keys used for records (see
- rreeccoorrddaa//33, etc.).
-
-
- ccuurrrreenntt__pprreeddiiccaattee((_?_N_a_m_e_, _?_H_e_a_d))
- Successively unifies _N_a_m_e with the name of predicates currently
- defined and _H_e_a_d with the most general term built from _N_a_m_e and the
- arity of the predicate. This predicate succeeds for all predicates
- defined in the specified module, imported to it, or in one of the
- modules from which the predicate will be imported if it is called.
-
-
- pprreeddiiccaattee__pprrooppeerrttyy((_?_H_e_a_d_, _?_P_r_o_p_e_r_t_y))
- Succeeds if _H_e_a_d refers to a predicate that has property _P_r_o_p_e_r_t_y.
- Can be used to test whether a predicate has a certain property,
- obtain all properties known for _H_e_a_d, find all predicates having
- _p_r_o_p_e_r_t_y or even obtaining all information available about the
- current program. _P_r_o_p_e_r_t_y is one of:
-
- iinntteerrpprreetteedd
- Is true if the predicate is defined in Prolog. We return true
- on this because, although the code is actually compiled, it is
- completely transparent, just like interpreted code.
-
- bbuuiilltt__iinn
- Is true if the predicate is locked as a built-in predicate.
- This implies it cannot be redefined in its definition module
- and it can normally not be seen in the tracer.
-
- ffoorreeiiggnn
- Is true if the predicate is defined in the C language.
-
- ddyynnaammiicc
- Is true if the predicate is declared dynamic using the
- ddyynnaammiicc//11 declaration.
-
- mmuullttiiffiillee
- Is true if the predicate is declared multifile using the
- mmuullttiiffiillee//11 declaration.
-
- uunnddeeffiinneedd
- Is true if a procedure definition block for the predicate
- exists, but there are no clauses in it and it is not declared
- dynamic. This is true if the predicate occurs in the body
- of a loaded predicate, an attempt to call it has been made
- via one of the meta-call predicates or the predicate had a
- definition in the past. See the library package _c_h_e_c_k for
- example usage.
-
- ttrraannssppaarreenntt
- Is true if the predicate is declared transparent using the
- mmoodduullee__ttrraannssppaarreenntt//11declaration.
-
- eexxppoorrtteedd
- Is true if the predicate is in the public list of the context
- module.
-
- iimmppoorrtteedd__ffrroomm((_M_o_d_u_l_e))
- Is true if the predicate is imported into the context module
- from module _M_o_d_u_l_e.
-
- iinnddeexxeedd((_H_e_a_d))
- Predicate is indexed (see iinnddeexx//11) according to _H_e_a_d. _H_e_a_d is
- a term whose name and arity are identical to the predicate.
- The arguments are unified with `1' for indexed arguments, `0'
- otherwise.
-
- ffiillee((_F_i_l_e_N_a_m_e))
- Unify _F_i_l_e_N_a_m_e with the name of the sourcefile in which the
- predicate is defined. See also ssoouurrccee__ffiillee//22.
-
- lliinnee__ccoouunntt((_L_i_n_e_N_u_m_b_e_r))
- Unify _L_i_n_e_N_u_m_b_e_r with the line number of the first clause of
- the predicate. Fails if the predicate is not associated with
- a file. See also ssoouurrccee__ffiillee//22.
-
- nnuummbbeerr__ooff__ccllaauusseess((_C_l_a_u_s_e_C_o_u_n_t))
- Unify _C_l_a_u_s_e_C_o_u_n_t to the number of clauses associated with the
- predicate. Fails for foreign predicates.
-
-
- ddwwiimm__pprreeddiiccaattee((_+_T_e_r_m_, _-_D_w_i_m))
- `Do What I Mean' (`dwim') support predicate. _T_e_r_m is a term, which
- name and arity are used as a predicate specification. _D_w_i_m is
- instantiated with the most general term built from _N_a_m_e and the
- arity of a defined predicate that matches the predicate specified
- by _T_e_r_m in the `Do What I Mean' sense. See ddwwiimm__mmaattcchh//22for `Do
- What I Mean' string matching. Internal system predicates are not
- generated, unless style_check(+dollar) is active. Backtracking
- provides all alternative matches.
-
-
- ccllaauussee((_?_H_e_a_d_, _?_B_o_d_y))
- Succeeds when _H_e_a_d can be unified with a clause head and _B_o_d_y
- with the corresponding clause body. Gives alternative clauses
- on backtracking. For facts _B_o_d_y is unified with the atom
- _t_r_u_e. Normally ccllaauussee//22 is used to find clause definitions for a
- predicate, but it can also be used to find clause heads for some
- body template.
-
-
- ccllaauussee((_?_H_e_a_d_, _?_B_o_d_y_, _?_R_e_f_e_r_e_n_c_e))
- Equivalent to ccllaauussee//22, but unifies _R_e_f_e_r_e_n_c_e with a unique
- reference to the clause (see also aasssseerrtt//22, eerraassee//11). If _R_e_f_e_r_e_n_c_e
- is instantiated to a reference the clause's head and body will be
- unified with _H_e_a_d and _B_o_d_y.
-
-
- nntthh__ccllaauussee((_?_P_r_e_d_, _?_I_n_d_e_x_, _?_R_e_f_e_r_e_n_c_e))
- Provides access to the clauses of a predicate using their index
- number. Counting starts at 1. If _R_e_f_e_r_e_n_c_e is specified it
- unifies _P_r_e_d with the most general term with the same name/arity
- as the predicate and _I_n_d_e_x with the index-number of the clause.
- Otherwise the name and arity of _P_r_e_d are used to determine the
- predicate. If _I_n_d_e_x is provided _R_e_f_e_r_e_n_c_e will be unified with
- the clause reference. If _I_n_d_e_x is unbound, backtracking will
- yield both the indices and the references of all clauses of the
- predicate. The following example finds the 2nd clause of mmeemmbbeerr//22:
-
- ?- nth_clause(member(_,_), 2, Ref), clause(Head, Body, Ref).
-
- Ref = 160088
- Head = system : member(G575, [G578|G579])
- Body = member(G575, G579)
-
-
- ccllaauussee__pprrooppeerrttyy((_+_C_l_a_u_s_e_R_e_f_, _-_P_r_o_p_e_r_t_y))
- Queries properties of a clause. _C_l_a_u_s_e_R_e_f is a reference
- to a clause as produced by ccllaauussee//33, nntthh__ccllaauussee//33 or
- pprroolloogg__ffrraammee__aattttrriibbuuttee//33. _P_r_o_p_e_r_t_y is one of the following:
-
- ffiillee((_F_i_l_e_N_a_m_e))
- Unify _F_i_l_e_N_a_m_e with the name of the sourcefile in which the
- clause is defined. Fails if the clause is not associated to a
- file.
-
- lliinnee__ccoouunntt((_L_i_n_e_N_u_m_b_e_r))
- Unify _L_i_n_e_N_u_m_b_e_r with the line number of the clause. Fails if
- the clause is not associated to a file.
-
- ffaacctt
- True if the clause has no body.
-
- eerraasseedd
- True if the clause has been erased, but not yet reclaimed
- because it is referenced.
-
-
- 33..1144 IInnppuutt aanndd OOuuttppuutt
-
- SWI-Prolog provides two different packages for input and output. One
- confirms to the Edinburgh standard. This package has a notion
- of `current-input' and `current-output'. The reading and writing
- predicates implicitly refer to these streams. In the second package,
- streams are opened explicitly and the resulting handle is used as an
- argument to the reading and writing predicate to specify the source or
- destination. Both packages are fully integrated; the user may switch
- freely between them.
-
-
- 33..1144..11 IInnppuutt aanndd OOuuttppuutt UUssiinngg IImmpplliicciitt SSoouurrccee aanndd DDeessttiinnaattiioonn
-
- The package for implicit input and output destination is upwards
- compatible to DEC-10 and C-Prolog. The reading and writing predicates
- refer to resp. the current input- and output stream. Initially these
- streams are connected to the terminal. The current output stream is
- changed using tteellll//11 or aappppeenndd//11. The current input stream is changed
- using sseeee//11. The streams current value can be obtained using tteelllliinngg//11
- for output- and sseeeeiinngg//11 for input streams. The table below shows the
- valid stream specifications. The reserved names user_input, user_output
- and user_error are for neat integration with the explicit streams.
-
- ___________________________________________________
- | user |This reserved name refers to the|
- | |terminal |
- | user_input I|nput from the terminal |
-
- | user_output O|utput to the terminal |
- | user_error U|nix error stream (output only) |
- | <_A_t_o_m> N|ame of a Unix file |
- |_pipe(<_A_t_o_m>)N|ame_of_a_Unix_command_____________|_
-
- Source and destination are either a file, one of the reserved words
- above, or a term `pipe(_C_o_m_m_a_n_d)'. In the predicate descriptions below
- we will call the source/destination argument `_S_r_c_D_e_s_t'. Below are some
- examples of source/destination specifications.
-
- ?- see(data). % Start reading from file `data'.
- ?- tell(stderr). % Start writing on the error stream.
-
- ?- tell(pipe(lpr)). % Start writing to the printer.
-
- Another example of using the ppiippee//11 construct is shown below. Note
- that the ppiippee//11 construct is not part of Prolog's standard I/O
- repertoire.
-
- getwd(Wd) :-
- seeing(Old), see(pipe(pwd)),
- collect_wd(String),
- seen, see(Old),
- atom_chars(Wd, String).
-
- collect_wd([C|R]) :-
- get0(C), C \== -1, !,
- collect_wd(R).
- collect_wd([]).
-
-
- sseeee((_+_S_r_c_D_e_s_t))
- Make _S_r_c_D_e_s_t the current input stream. If _S_r_c_D_e_s_t was already
- opened for reading with sseeee//11 and has not been closed since,
- reading will be resumed. Otherwise _S_r_c_D_e_s_t will be opened and the
- file pointer is positioned at the start of the file.
-
-
- tteellll((_+_S_r_c_D_e_s_t))
- Make _S_r_c_D_e_s_t the current output stream. If _S_r_c_D_e_s_t was already
- opened for writing with tteellll//11 or aappppeenndd//11 and has not been closed
- since, writing will be resumed. Otherwise the file is created
- or---when existing---truncated. See also aappppeenndd//11.
-
-
- aappppeenndd((_+_F_i_l_e))
- Similar to tteellll//11, but positions the file pointer at the end of
- _F_i_l_e rather than truncating an existing file. The pipe construct
- is not accepted by this predicate.
-
-
- sseeeeiinngg((_?_S_r_c_D_e_s_t))
- Unify the name of the current input stream with _S_r_c_D_e_s_t.
-
-
- tteelllliinngg((_?_S_r_c_D_e_s_t))
- Unify the name of the current output stream with _S_r_c_D_e_s_t.
-
-
- sseeeenn
- Close the current input stream. The new input stream becomes _u_s_e_r.
-
-
- ttoolldd
- Close the current output stream. The new output stream becomes
- _u_s_e_r.
-
-
- 33..1144..22 EExxpplliicciitt IInnppuutt aanndd OOuuttppuutt SSttrreeaammss
-
- The predicates below are part of the Quintus compatible stream-based
- I/O package. In this package streams are explicitly created using the
- predicate ooppeenn//33. The resulting stream identifier is then passed as a
- parameter to the reading and writing predicates to specify the source
- or destination of the data.
-
-
- ooppeenn((_+_S_r_c_D_e_s_t_, _+_M_o_d_e_, _-_S_t_r_e_a_m_, _+_O_p_t_i_o_n_s))
- ISO compliant predicate to open a stream. _S_r_c_D_e_s is either an
- atom, specifying a Unix file, or a term `pipe(Command)', just
- like sseeee//11 and tteellll//11. _M_o_d_e is one of read, write, append or
- update. Mode append opens the file for writing, positioning the
- file-pointer at the end. Mode update opens the file for writing,
- positioning the file-pointer at the beginning of the file without
- truncating the file. See also ssttrreeaamm__ppoossiittiioonn//33. _S_t_r_e_a_m is either
- a variable, in which case it is bound to an integer identifying the
- stream, or an atom, in which case this atom will be the stream
- identifier. The _O_p_t_i_o_n_s list can contain the following options:
-
- ttyyppee((_T_y_p_e))
- Using type text (default), Prolog will write a text-file in an
- operating-system compatible way. Using type binary the bytes
- will be read or written without any translation. Note there
- is no difference between the two on Unix systems.
-
- aalliiaass((_A_t_o_m))
- Gives the stream a name. The following two calls are
- identical, but only the latter is allowed in ISO Prolog.
-
- ?- open(foo, read, in, []).
- ?- open(foo, read, S, [alias(in)]).
-
- eeooff__aaccttiioonn((_A_c_t_i_o_n))
- Defines what happens if the end of the input stream is
- reached. Action eof_code makes ggeett00//11 and friends return -1
- and rreeaadd//11 and friends return the atom end_of_file. Repetitive
- reading keeps yielding the same result. Action error is like
- eof_code, but repetitive reading will raise an error. With
- action reset, Prolog will examine the file again and return
- more data if the file has grown.
-
- bbuuffffeerr((_B_u_f_f_e_r_i_n_g))
- Defines output buffering. The atom fullf (default) defines
- full buffering, line buffering by line, and false implies the
- stream is fully unbuffered. Smaller buffering is useful if
- another process or the user is waiting for the output as it is
- being produced. See also fflluusshh//00 and fflluusshh__oouuttppuutt//11. This
- option is not an ISO option.
-
- cclloossee__oonn__aabboorrtt((_B_o_o_l))
- If true (default), the stream is closed on an abort (see
- aabboorrtt//00). If false, the stream is not closed. If it is
- an output stream, it will be flushed however. Useful for
- logfiles and if the stream is associated to a process (using
- the ppiippee//11 construct).
-
- The option reposition is not supported in SWI-Prolog. All streams
- connected to a file may be repositioned.
-
-
- ooppeenn((_+_S_r_c_D_e_s_t_, _+_M_o_d_e_, _?_S_t_r_e_a_m))
- Equivalent to ooppeenn//44 with an empty option-list.
-
-
- ooppeenn__nnuullll__ssttrreeaamm((_?_S_t_r_e_a_m))
- Open a stream that produces no output. All counting functions are
- enabled on such a stream. An attempt to read from a null-stream
- will immediately signal end-of-file. Similar to Unix /dev/null.
- _S_t_r_e_a_m can be an atom, giving the null-stream an alias name.
-
-
- cclloossee((_+_S_t_r_e_a_m))
-
- Close the specified stream. If _S_t_r_e_a_m is not open an error message
- is displayed. If the closed stream is the current input or output
- stream the terminal is made the current input or output.
-
-
- ccuurrrreenntt__ssttrreeaamm((_?_F_i_l_e_, _?_M_o_d_e_, _?_S_t_r_e_a_m))
- Is true if a stream with file specification _F_i_l_e, mode _M_o_d_e and
- stream identifier _S_t_r_e_a_m is open. The reserved streams user and
- user_error are not generated by this predicate. If a stream has
- been opened with mode append this predicate will generate mode
- write.
-
-
- ssttrreeaamm__ppoossiittiioonn((_+_S_t_r_e_a_m_, _-_O_l_d_, _+_N_e_w))
- Unify the position parameters of _S_t_r_e_a_m with _O_l_d and set them to
- _N_e_w. A position is represented by the following term:
-
- '$stream_position'(CharNo, LineNo, LinePos).
-
- It is only possible to change the position parameters if the stream
- is connected to a disk file. If the position is changed, the
- _C_h_a_r_N_o field determines the new position in the file. The _L_i_n_e_N_o
- and _L_i_n_e_P_o_s are copied in the stream administration.
-
-
- 33..1144..33 SSwwiittcchhiinngg BBeettwweeeenn IImmpplliicciitt aanndd EExxpplliicciitt II//OO
-
- The predicates below can be used for switching between the implicit-
- and the explicit stream based I/O predicates.
-
-
- sseett__iinnppuutt((_+_S_t_r_e_a_m))
- Set the current input stream to become _S_t_r_e_a_m. Thus, open(file,
- read, Stream), set_input(Stream) is equivalent to see(file).
-
-
- sseett__oouuttppuutt((_+_S_t_r_e_a_m))
- Set the current output stream to become _S_t_r_e_a_m.
-
-
- ccuurrrreenntt__iinnppuutt((_-_S_t_r_e_a_m))
- Get the current input stream. Useful to get access to the status
- predicates associated with streams.
-
-
- ccuurrrreenntt__oouuttppuutt((_-_S_t_r_e_a_m))
- Get the current output stream.
-
-
- dduupp__ssttrreeaamm((_+_F_r_o_m_, _+_T_o))
- Duplicate the underlying data from stream _F_r_o_m to streamTo, so
- actions performed on either stream have the same effect. The
- primary goal of this predicate is to facilitate redirection of
- the user interaction to allow for `interactor' windows. For
- example, the following code will redirect output to user_output and
- user_error to an XPCE text window:
-
- ...,
- pce_open(Window, append, Fd),
- dup_stream(user_output, Fd),
- dup_stream(user_error, Fd),
- ...
-
- The old status of a stream can be stored by duplicating to a
- null-stream as obtained using ooppeenn__nnuullll__ssttrreeaamm//11.
-
- This predicate is SWI-Prolog specific.
-
-
- 33..1155 SSttaattuuss ooff IInnppuutt aanndd OOuuttppuutt SSttrreeaammss
-
-
- wwaaiitt__ffoorr__iinnppuutt((_+_L_i_s_t_O_f_S_t_r_e_a_m_s_, _-_R_e_a_d_y_L_i_s_t_, _+_T_i_m_e_O_u_t))
- Wait for input on one of the streams in _L_i_s_t_O_f_S_t_r_e_a_m_s and return
- a list of streams on which input is available in _R_e_a_d_y_L_i_s_t.
- wwaaiitt__ffoorr__iinnppuutt//33 waits for at most _T_i_m_e_O_u_t seconds. _T_i_m_e_o_u_t may
- be specified as a floating point number to specify fractions of a
- second. If _T_i_m_e_o_u_t equals 0, wwaaiitt__ffoorr__iinnppuutt//33waits indefinitely.
- This predicate can be used to implement timeout while reading and
- to handle input from multiple sources. The following example
- will wait for input from the user and an explicitly opened second
- terminal. On return, _I_n_p_u_t_s may hold user or _P_4 or both.
-
- ?- open('/dev/ttyp4', read, P4),
- wait_for_input([user, P4], Inputs, 0).
-
-
- cchhaarraacctteerr__ccoouunntt((_+_S_t_r_e_a_m_, _-_C_o_u_n_t))
- Unify _C_o_u_n_t with the current character index. For input streams
- this is the number of characters read since the open, for output
- streams this is the number of characters written. Counting starts
- at 0.
-
-
- lliinnee__ccoouunntt((_+_S_t_r_e_a_m_, _-_C_o_u_n_t))
- Unify _C_o_u_n_t with the number of lines read or written. Counting
- starts at 1.
-
-
- lliinnee__ppoossiittiioonn((_+_S_t_r_e_a_m_, _-_C_o_u_n_t))
- Unify _C_o_u_n_t with the position on the current line. Note that this
- assumes the position is 0 after the open. Tabs are assumed to be
- defined on each 8-th character and backspaces are assumed to reduce
- the count by one, provided it is positive.
-
-
- ffiilleeeerrrroorrss((_-_O_l_d_, _+_N_e_w))
- Define error behaviour on errors when opening a file for reading or
- writing. Valid values are the atoms on (default) and off. First
- _O_l_d is unified with the current value. Then the new value is set
- to _N_e_w.
-
-
- 33..1166 PPrriimmiittiivvee CChhaarraacctteerr IInnppuutt aanndd OOuuttppuutt
-
-
- nnll
- Write a newline character to the current output stream. On Unix
- systems nnll//00 is equivalent to put(10).
-
-
- nnll((_+_S_t_r_e_a_m))
- Write a newline to _S_t_r_e_a_m.
-
-
- ppuutt((_+_C_h_a_r))
- Write _C_h_a_r to the current output stream, _C_h_a_r is either an
- integer-expression evaluating to an ASCII value (0 _C_h_a_r 255) or
- an atom of one character.
-
-
- ppuutt((_+_S_t_r_e_a_m_, _+_C_h_a_r))
- Write _C_h_a_r to _S_t_r_e_a_m.
-
-
- ttaabb((_+_A_m_o_u_n_t))
- Writes _A_m_o_u_n_t spaces on the current output stream. _A_m_o_u_n_t
- should be an expression that evaluates to a positive integer (see
- section 3.22).
-
-
- ttaabb((_+_S_t_r_e_a_m_, _+_A_m_o_u_n_t))
- Writes _A_m_o_u_n_t spaces to _S_t_r_e_a_m.
-
-
- fflluusshh
- Flush pending output on current output stream. fflluusshh//00 is
- automatically generated by rreeaadd//11 and derivatives if the current
- input stream is user and the cursor is not at the left margin.
-
-
- fflluusshh__oouuttppuutt((_+_S_t_r_e_a_m))
- Flush output on the specified stream. The stream must be open for
- writing.
-
-
- ttttyyfflluusshh
- Flush pending output on stream _u_s_e_r. See also fflluusshh//00.
-
-
- ggeett00((_-_C_h_a_r))
- Read the current input stream and unify the next character with
- _C_h_a_r. _C_h_a_r is unified with -1 on end of file.
-
-
- ggeett00((_+_S_t_r_e_a_m_, _-_C_h_a_r))
- Read the next character from _S_t_r_e_a_m.
-
-
- ggeett((_-_C_h_a_r))
- Read the current input stream and unify the next non-blank
- character with _C_h_a_r. _C_h_a_r is unified with -1 on end of file.
-
-
- ggeett((_+_S_t_r_e_a_m_, _-_C_h_a_r))
- Read the next non-blank character from _S_t_r_e_a_m.
-
-
- ppeeeekk__bbyyttee((_-_C_h_a_r))
- Reads the next input character like ggeett00//11, but does not remove it
- from the input stream. This predicate is ISO compliant.
-
-
- ppeeeekk__bbyyttee((_+_S_t_r_e_a_m_, _-_C_h_a_r))
- Reads the next input character like ggeett00//22, but does not remove it
- from the stream. This predicate is ISO compliant.
-
-
- sskkiipp((_+_C_h_a_r))
- Read the input until _C_h_a_r or the end of the file is encountered. A
- subsequent call to ggeett00//11 will read the first character after _C_h_a_r.
-
-
- sskkiipp((_+_S_t_r_e_a_m_, _+_C_h_a_r))
- Skip input (as sskkiipp//11) on _S_t_r_e_a_m.
-
-
- ggeett__ssiinnggllee__cchhaarr((_-_C_h_a_r))
- Get a single character from input stream `user' (regardless of the
- current input stream). Unlike ggeett00//11 this predicate does not wait
- for a return. The character is not echoed to the user's terminal.
- This predicate is meant for keyboard menu selection etc.. If
- SWI-Prolog was started with the -tty option this predicate reads an
- entire line of input and returns the first non-blank character on
- this line, or the ASCII code of the newline (10) if the entire line
- consisted of blank characters.
-
-
- aatt__eenndd__ooff__ssttrreeaamm
- Succeeds after the last character of the current input stream has
- been read. Also succeeds if there is no valid current input
- stream.
-
-
- aatt__eenndd__ooff__ssttrreeaamm((_+_S_t_r_e_a_m))
- Succeeds after the last character of the named stream is read, or
- _S_t_r_e_a_m is not a valid input stream.
-
-
- 33..1177 TTeerrmm RReeaaddiinngg aanndd WWrriittiinngg
-
- This section describes the basic term reading and writing predicates.
- The predicates tteerrmm__ttoo__aattoomm//22 and aattoomm__ttoo__tteerrmm//33 provide means for
- translating atoms and strings to terms. The predicates ffoorrmmaatt//[[11,,22]]
- and wwrriitteeff//22 provide formatted output.
-
- There are two ways to manipulate the output format. The predicate
- pprriinntt//[[11,,22]] may be programmed using ppoorrttrraayy//11. The format of floating
- point numbers may be manipulated using the feature (see ffeeaattuurree//22)
- float_format.
-
- Reading is sensitive to the feature character_escapes, which controls
- the interpretation of the \ character in quoted atoms and strings.
-
-
- wwrriittee__tteerrmm((_+_T_e_r_m_, _+_O_p_t_i_o_n_s))
- The predicate wwrriittee__tteerrmm//22 is the generic form of all Prolog
- term-write predicates. Valid options are:
-
- qquuootteedd((true _o_r false))
- If true, atoms and functors that needs quotes will be quoted.
- The default is false.
-
- iiggnnoorree__ooppss((true _o_r false))
- If true, the generic term-representation (<_f_u_n_c_t_o_r>(<_a_r_g_s> ...))
- will be used for all terms, Otherwise (default), operators,
- list-notation and {}/1 will be written using their special
- syntax.
-
- nnuummbbeerrvvaarrss((true _o_r false))
- If true, terms of the format $VAR(N), where <_N> is a positive
- integer, will be written as a variable name. The default is
- false.
-
- ppoorrttrraayy((true _o_r false))
- If true, the hook ppoorrttrraayy//11 is called before printing a term
- that is not a variable. If ppoorrttrraayy//11 succeeds, the term is
- considered printed. See also pprriinntt//11. The default is false.
- This option is an extension to the ISO write_term options.
-
-
- wwrriittee__tteerrmm((_+_S_t_r_e_a_m_, _+_T_e_r_m_, _+_O_p_t_i_o_n_s))
- As wwrriittee__tteerrmm//22, but output is sent to _S_t_r_e_a_m rather than the
- current output.
-
-
- wwrriittee__ccaannoonniiccaall((_+_T_e_r_m))
- Write _T_e_r_m on the current output stream using standard parenthe-
- sised prefix notation (i.e. ignoring operator declarations). Atoms
- that need quotes are quoted. Terms written with this predicate can
- always be read back, regardless of current operator declarations.
- Equivalent to wwrriittee__tteerrmm//22 using the options ignore_ops and quoted.
-
-
- wwrriittee__ccaannoonniiccaall((_+_S_t_r_e_a_m_, _+_T_e_r_m))
- Write _T_e_r_m in canonical form on _S_t_r_e_a_m.
-
-
- wwrriittee((_+_T_e_r_m))
- Write _T_e_r_m to the current output, using brackets and operators
- where appropriate. See ffeeaattuurree//22 for controlling floating point
- output format.
-
-
- wwrriittee((_+_S_t_r_e_a_m_, _+_T_e_r_m))
- Write _T_e_r_m to _S_t_r_e_a_m.
-
-
- wwrriitteeqq((_+_T_e_r_m))
- Write _T_e_r_m to the current output, using brackets and operators
- where appropriate. Atoms that need quotes are quoted. Terms
- written with this predicate can be read back with rreeaadd//11 provided
- the currently active operator declarations are identical.
-
-
- wwrriitteeqq((_+_S_t_r_e_a_m_, _+_T_e_r_m))
- Write _T_e_r_m to _S_t_r_e_a_m, inserting quotes.
-
-
- pprriinntt((_+_T_e_r_m))
- Prints _T_e_r_m on the current output stream similar to wwrriittee//11, but
- for each (sub)term of _T_e_r_m first the dynamic predicate ppoorrttrraayy//11 is
- called. If this predicate succeeds _p_r_i_n_t assumes the (sub)term has
- been written. This allows for user defined term writing.
-
-
- pprriinntt((_+_S_t_r_e_a_m_, _+_T_e_r_m))
- Print _T_e_r_m to _S_t_r_e_a_m.
-
-
- ppoorrttrraayy((_+_T_e_r_m))
- A dynamic predicate, which can be defined by the user to change the
- behaviour of pprriinntt//11 on (sub)terms. For each subterm encountered
- that is not a variable pprriinntt//11 first calls ppoorrttrraayy//11 using the term
- as argument. For lists only the list as a whole is given to
- ppoorrttrraayy//11. If portray succeeds pprriinntt//11 assumes the term has been
- written.
-
-
- rreeaadd((_-_T_e_r_m))
- Read the next Prolog term from the current input stream and unify
- it with _T_e_r_m. On a syntax error rreeaadd//11 displays an error message,
- attempts to skip the erroneous term and fails. On reaching
- end-of-file _T_e_r_m is unified with the atom end_of_file.
-
-
- rreeaadd((_+_S_t_r_e_a_m_, _-_T_e_r_m))
- Read _T_e_r_m from _S_t_r_e_a_m.
-
-
- rreeaadd__ccllaauussee((_-_T_e_r_m))
- Equivalent to rreeaadd//11, but warns the user for variables only
- occurring once in a term (singleton variables) which do not start
- with an underscore if style_check(singleton) is active (default).
- Used to read Prolog source files (see ccoonnssuulltt//11). New code should
- use rreeaadd__tteerrmm//22 with the option singletons(warning).
-
-
- rreeaadd__ccllaauussee((_+_S_t_r_e_a_m_, _-_T_e_r_m))
- Read a clause from _S_t_r_e_a_m. See rreeaadd__ccllaauussee//11.
-
-
- rreeaadd__vvaarriiaabblleess((_-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
- Similar to rreeaadd//11, but _B_i_n_d_i_n_g_s is unified with a list of
- `_N_a_m_e = _V_a_r' tuples, thus providing access to the actual variable
- names. New code should use rreeaadd__tteerrmm//22 using the option
- variables(X).
-
-
- rreeaadd__vvaarriiaabblleess((_+_S_t_r_e_a_m_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
- Read, returning term and bindings from _S_t_r_e_a_m. See
- rreeaadd__vvaarriiaabblleess//22.
-
-
- rreeaadd__tteerrmm((_-_T_e_r_m_, _+_O_p_t_i_o_n_s))
- Read a term from the current input stream and unify the term with
- _T_e_r_m. The reading is controlled by options from the list of
- _O_p_t_i_o_n_s. If this list is empty, the behaviour is the same as for
- rreeaadd//11. The options are upward compatible to Quintus Prolog. The
- argument order is according to the ISO standard. Options:
-
- ssyynnttaaxx__eerrrroorrss((_a_t_o_m _o_r _v_a_r_i_a_b_l_e))
- Define the behaviour for when a syntax error occurs. The
- possible values are:
-
- ffaaiill
- Default behaviour. The error is reported as a warning and
- the predicate fails.
-
- qquuiieett
- Quietly fails if a syntax error has occurred.
-
- VVaarriiaabbllee
- If no error occurs, the variable is unified with none,
- otherwise _V_a_r_i_a_b_l_e is unified with a term of the form
-
- '$stream_position'(CharNo, LineNo, LinePos):Message
-
- This behaviour is a SWI-Prolog extension.
-
- vvaarriiaabbllee__nnaammeess((_V_a_r_s))
- Unify _V_a_r_s with a list of `_N_a_m_e = _V_a_r', where _N_a_m_e is an atom
- describing the variable name and _V_a_r is a variable that shares
- with the corresponding variable in _T_e_r_m.
-
- ssiinngglleettoonnss((_V_a_r_s))
- As variable_names, but only reports the variables occurring
- only once in the _T_e_r_m read. Variables starting with an
- underscore (`_') are not included in this list.
-
- tteerrmm__ppoossiittiioonn((_P_o_s))
- Unifies _P_o_s with the starting position of the term read. _P_o_s
- if of the same format as use by ssttrreeaamm__ppoossiittiioonn//33.
-
- ssuubbtteerrmm__ppoossiittiioonnss((_T_e_r_m_P_o_s))
- Describes the detailed layout of the term. The formats for
- the various types of terms if given below. All positions are
- character positions. If the input is related to a normal
- stream, these positions are relative to the start of the
- input, when reading from the terminal, they are relative to
- the start of the term.
-
- FFrroomm--TToo
- Used for primitive types (atoms, numbers, variables).
-
- ssttrriinngg__ppoossiittiioonn((_F_r_o_m_, _T_o))
- Used to indicate the position of a string enclosed in
- double quotes (").
-
- bbrraaccee__tteerrmm__ppoossiittiioonn((_F_r_o_m_, _T_o_, _A_r_g))
- Term of the form {...}, as used in DCG rules. _A_r_g
- describes the argument.
-
- lliisstt__ppoossiittiioonn((_F_r_o_m_, _T_o_, _E_l_m_s_, _T_a_i_l))
- A list. _E_l_m_s describes the positions of the elements. If
- the list specifies the tail as |<_T_a_i_l_T_e_r_m>, _T_a_i_l is unified
- with the term-position of the tail, otherwise with the
- atom none.
-
- tteerrmm__ppoossiittiioonn((_F_r_o_m_, _T_o_, _F_F_r_o_m_, _F_T_o_, _S_u_b_P_o_s))
- Used for a compound term not matching one of the above.
- _F_F_r_o_m and _F_T_o describe the position of the functor.
- _S_u_b_P_o_s is a list, each element of which describes the
- term-position of the corresponding subterm.
-
-
- rreeaadd__tteerrmm((_+_S_t_r_e_a_m_, _-_T_e_r_m_, _+_O_p_t_i_o_n_s))
- Read term with options from _S_t_r_e_a_m. See rreeaadd__tteerrmm//22.
-
-
- rreeaadd__hhiissttoorryy((_+_S_h_o_w_, _+_H_e_l_p_, _+_S_p_e_c_i_a_l_, _+_P_r_o_m_p_t_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
- Similar to rreeaadd__vvaarriiaabblleess//22, but allows for history substitutions.
- rreeaadd__hhiissttoorryy//66 is used by the top level to read the user's actions.
- _S_h_o_w is the command the user should type to show the saved events.
- _H_e_l_p is the command to get an overview of the capabilities.
- _S_p_e_c_i_a_l is a list of commands that are not saved in the history.
- _P_r_o_m_p_t is the first prompt given. Continuation prompts for
- more lines are determined by pprroommpptt//22. A %w in the prompt is
- substituted by the event number. See section 2.4 for available
- substitutions.
-
- SWI-Prolog calls rreeaadd__hhiissttoorryy//66 as follows:
-
- read_history(h, '!h', [trace], '%w ?- ', Goal, Bindings)
-
-
- pprroommpptt((_-_O_l_d_, _+_N_e_w))
- Set prompt associated with rreeaadd//11 and its derivatives. _O_l_d is
- first unified with the current prompt. On success the prompt will
- be set to _N_e_w if this is an atom. Otherwise an error message is
- displayed. A prompt is printed if one of the read predicates is
- called and the cursor is at the left margin. It is also printed
- whenever a newline is given and the term has not been terminated.
- Prompts are only printed when the current input stream is _u_s_e_r.
-
-
- pprroommpptt11((_+_P_r_o_m_p_t))
- Sets the prompt for the next line to be read. Continuation lines
- will be read using the prompt defined by pprroommpptt//22.
-
-
- 33..1188 AAnnaallyyssiinngg aanndd CCoonnssttrruuccttiinngg TTeerrmmss
-
-
- ffuunnccttoorr((_?_T_e_r_m_, _?_F_u_n_c_t_o_r_, _?_A_r_i_t_y))
- Succeeds if _T_e_r_m is a term with functor _F_u_n_c_t_o_r and arity _A_r_i_t_y.
- If _T_e_r_m is a variable it is unified with a new term holding only
- variables. ffuunnccttoorr//33 silently fails on instantiation faults If
- _T_e_r_m is an atom or number, _F_u_n_c_t_o_r will be unified with _T_e_r_m and
- arity will be unified with the integer 0 (zero).
-
-
- aarrgg((_?_A_r_g_, _?_T_e_r_m_, _?_V_a_l_u_e))
- _T_e_r_m should be instantiated to a term, _A_r_g to an integer between
- 1 and the arity of _T_e_r_m. _V_a_l_u_e is unified with the _A_r_g-th
- argument of _T_e_r_m. _A_r_g may also be unbound. In this case _V_a_l_u_e
- will be unified with the successive arguments of the term. On
- successful unification, _A_r_g is unified with the argument number.
- Backtracking yields alternative solutions. The predicate aarrgg//33
- fails silently if _A_r_g= 0 or _A_r_g > _a_r_i_t_y and raises the exception
- domain_error(not_less_then_zero, Arg)if _A_r_g <0.
-
-
- sseettaarrgg((_+_A_r_g_, _+_T_e_r_m_, _+_V_a_l_u_e))
- Extra-logical predicate. Assigns the _A_r_g-th argument of the
- compound term _T_e_r_m with the given _V_a_l_u_e. The assignment is undone
- if backtracking brings the state back into a position before the
- sseettaarrgg//33 call.
-
- This predicate may be used for destructive assignment to terms,
- using them as and extra-logical storage bin.
-
-
- _?_T_e_r_m =.. _?_L_i_s_t
- _L_i_s_t is a list which head is the functor of _T_e_r_m and the remaining
- arguments are the arguments of the term. Each of the arguments may
- be a variable, but not both. This predicate is called `Univ'.
- Examples:
-
- ?- foo(hello, X) =.. List.
-
- List = [foo, hello, X]
-
- ?- Term =.. [baz, foo(1)]
-
- Term = baz(foo(1))
-
-
- nnuummbbeerrvvaarrss((_+_T_e_r_m_, _+_F_u_n_c_t_o_r_, _+_S_t_a_r_t_, _-_E_n_d))
- Unify the free variables of _T_e_r_m with a term constructed from the
- atom _F_u_n_c_t_o_r with one argument. The argument is the number of the
- variable. Counting starts at _S_t_a_r_t. _E_n_d is unified with the
- number that should be given to the next variable. Example:
-
- ?- numbervars(foo(A, B, A), this_is_a_variable, 0, End).
-
- A = this_is_a_variable(0)
- B = this_is_a_variable(1)
- End = 2
-
- In Edinburgh Prolog the second argument is missing. It is fixed to
- be $VAR.
-
-
- ffrreeee__vvaarriiaabblleess((_+_T_e_r_m_, _-_L_i_s_t))
- Unify _L_i_s_t with a list of variables, each sharing with a unique
- variable of _T_e_r_m. For example:
-
- ?- free_variables(a(X, b(Y, X), Z), L).
-
- L = [G367, G366, G371]
- X = G367
- Y = G366
- Z = G371
-
-
- ccooppyy__tteerrmm((_+_I_n_, _-_O_u_t))
- Make a copy of term _I_n and unify the result with _O_u_t. Ground parts
- of _I_n are shared by _O_u_t. Provided _I_n and _O_u_t have no sharing
- variables before this call they will have no sharing variables
- afterwards. ccooppyy__tteerrmm//22 is semantically equivalent to:
-
- copy_term(In, Out) :-
- recorda(copy_key, In, Ref),
- recorded(copy_key, Out, Ref),
- erase(Ref).
-
-
- 33..1199 AAnnaallyyssiinngg aanndd CCoonnssttrruuccttiinngg AAttoommss
-
- These predicates convert between Prolog constants and lists of ASCII
- values. The predicates aattoomm__cchhaarrss//22, nnuummbbeerr__cchhaarrss//22 and nnaammee//22 behave
- the same when converting from a constant to a list of ASCII values.
- When converting the other way around, aattoomm__cchhaarrss//22 will generate an
- atom, number_chars will generate a number or fail and nnaammee//22 will return
- a number if possible and an atom otherwise.
-
-
- aattoomm__cchhaarrss((_?_A_t_o_m_, _?_S_t_r_i_n_g))
- Convert between an atom and a list of ASCII values. If _A_t_o_m is
- instantiated, if will be translated into a list of ASCII values and
- the result is unified with _S_t_r_i_n_g. If _A_t_o_m is unbound and _S_t_r_i_n_g
- is a list of ASCII values, it will _A_t_o_m will be unified with an
- atom constructed from this list.
-
-
- aattoomm__cchhaarr((_?_A_t_o_m_, _?_A_S_C_I_I))
- Convert between character and ASCII value for a single character.
-
-
- nnuummbbeerr__cchhaarrss((_?_N_u_m_b_e_r_, _?_S_t_r_i_n_g))
- Similar to aattoomm__cchhaarrss//22, but converts between a number and its
- representation as a list of ASCII values. Fails silently if _N_u_m_b_e_r
- is unbound and _S_t_r_i_n_g does not describe a number.
-
-
- nnaammee((_?_A_t_o_m_O_r_I_n_t_, _?_S_t_r_i_n_g))
- _S_t_r_i_n_g is a list of ASCII values describing _A_t_o_m. Each of the
- arguments may be a variable, but not both. When _S_t_r_i_n_g is bound to
- an ASCII value list describing an integer and _A_t_o_m is a variable
- _A_t_o_m will be unified with the integer value described by _S_t_r_i_n_g
- (e.g. `name(N, "300"), 400 is N + 100' succeeds).
-
-
- iinntt__ttoo__aattoomm((_+_I_n_t_, _+_B_a_s_e_, _-_A_t_o_m))
- Convert _I_n_t to an ascii representation using base _B_a_s_e and unify
- the result with _A_t_o_m. If _B_a_s_e 6=10 the base will be prepended to
- _A_t_o_m. _B_a_s_e= 0 will try to interpret _I_n_t as an ASCII value and
- return 0'<_c>. Otherwise 2 _B_a_s_e 36. Some examples are given
- below.
-
- int_to_atom(45, 2, A) -! A= 20101101
- int_to_atom(97, 0, A) -! A= 00a
- int_to_atom(56, 10, A) -! A= 56
-
-
- iinntt__ttoo__aattoomm((_+_I_n_t_, _-_A_t_o_m))
- Equivalent to int_to_atom(Int, 10, Atom).
-
-
- tteerrmm__ttoo__aattoomm((_?_T_e_r_m_, _?_A_t_o_m))
- Succeeds if _A_t_o_m describes a term that unifies with _T_e_r_m. When
- _A_t_o_m is instantiated _A_t_o_m is converted and then unified with _T_e_r_m.
- Otherwise _T_e_r_m is ``written'' on _A_t_o_m using wwrriittee//11.
-
-
- aattoomm__ttoo__tteerrmm((_+_A_t_o_m_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
- Use _A_t_o_m as input to rreeaadd__vvaarriiaabblleess//22and return the read term in
- _T_e_r_m and the variable bindings in _B_i_n_d_i_n_g_s. _B_i_n_d_i_n_g_s is a list of
- _N_a_m_e = _V_a_r couples, thus providing access to the actual variable
- names. See also rreeaadd__vvaarriiaabblleess//22.
-
-
- ccoonnccaatt((_?_A_t_o_m_1_, _?_A_t_o_m_2_, _?_A_t_o_m_3))
- _A_t_o_m_3 forms the concatenation of _A_t_o_m_1 and _A_t_o_m_2. At least two of
- the arguments must be instantiated to atoms, integers or floating
- point numbers.
-
-
- ccoonnccaatt__aattoomm((_+_L_i_s_t_, _-_A_t_o_m))
- _L_i_s_t is a list of atoms, integers or floating point numbers.
- Succeeds if _A_t_o_m can be unified with the concatenated elements of
- _L_i_s_t. If _L_i_s_t has exactly 2 elements it is equivalent to ccoonnccaatt//33,
- allowing for variables in the list.
-
-
- ccoonnccaatt__aattoomm((_+_L_i_s_t_, _+_S_e_p_a_r_a_t_o_r_, _-_A_t_o_m))
- Creates an atom just like ccoonnccaatt__aattoomm//22, but inserts _S_e_p_a_r_a_t_o_r
- between each pair of atoms. For example:
-
- ?- concat_atom([gnu, gnat], ', ', A).
-
- A = 'gnu, gnat'
-
-
- aattoomm__lleennggtthh((_+_A_t_o_m_, _-_L_e_n_g_t_h))
- Succeeds if _A_t_o_m is an atom of _L_e_n_g_t_h characters long. This
- predicate also works for integers and floats, expressing the number
- of characters output when given to wwrriittee//11.
-
-
- aattoomm__pprreeffiixx((_+_A_t_o_m_, _+_P_r_e_f_i_x))
- Succeeds if _A_t_o_m starts with the characters from _P_r_e_f_i_x. Its
- behaviour is equivalent to ?- concat(Prefix, _, Atom), but avoids
- the construction of an atom for the `remainder'.
-
-
- 33..2200 RReepprreesseennttiinngg TTeexxtt iinn SSttrriinnggss
-
- SWI-Prolog supports the data type _s_t_r_i_n_g. Strings are a time and
- space efficient mechanism to handle text in Prolog. Atoms are under
- some circumstances not suitable because garbage collection on them is
- next to impossible (Although it is possible: BIM_prolog does it).
- Representing text as a list of ASCII values is, from the logical point
- of view, the cleanest solution. It however has two drawbacks: 1) they
- cannot be distinguished from a list of (small) integers; and 2) they
- consume (in SWI-Prolog) 12 bytes for each character stored.
-
- Within strings each character only requires 1 byte storage. Strings
- live on the global stack and their storage is thus reclaimed on
- backtracking. Garbage collection can easily deal with strings.
-
- The ISO standard proposes " ..." is transformed into a string object by
- rreeaadd//11 and derivatives. This poses problems as in the old convention
- " ..." is transformed into a list of ascii characters. For this reason
- the style check option `string' is available (see ssttyyllee__cchheecckk//11).
-
- The set of predicates associated with strings is incomplete and
- tentative. Names and definitions might change in the future to confirm
- to the emerging standard.
-
-
- ssttrriinngg__ttoo__aattoomm((_?_S_t_r_i_n_g_, _?_A_t_o_m))
- Logical conversion between a string and an atom. At least one
- of the two arguments must be instantiated. _A_t_o_m can also be an
- integer or floating point number.
-
-
- ssttrriinngg__ttoo__lliisstt((_?_S_t_r_i_n_g_, _?_L_i_s_t))
- Logical conversion between a string and a list of ASCII characters.
- At least one of the two arguments must be instantiated.
-
-
- ssttrriinngg__lleennggtthh((_+_S_t_r_i_n_g_, _-_L_e_n_g_t_h))
- Unify _L_e_n_g_t_h with the number of characters in _S_t_r_i_n_g. This
- predicate is functionally equivalent to aattoomm__lleennggtthh//22 and also
- accepts atoms, integers and floats as its first argument.
-
-
- ssttrriinngg__ccoonnccaatt((_?_S_t_r_i_n_g_1_, _?_S_t_r_i_n_g_2_, _?_S_t_r_i_n_g_3))
- Similar to ccoonnccaatt//33, but the unbound argument will be unified with
- a string object rather than an atom. Also, if both _S_t_r_i_n_g_1
- and _S_t_r_i_n_g_2 are unbound and _S_t_r_i_n_g_3 is bound to text, it breaks
- _S_t_r_i_n_g_3, unifying the start with _S_t_r_i_n_g_1 and the end with _S_t_r_i_n_g_2
- as append does with lists. Note that this is not particularly
- fast on long strings as for each redo the system has to create
- two entirely new strings, while the list equivalent only creates a
- single new list-cell and moves some pointers around.
-
-
- ssuubbssttrriinngg((_+_S_t_r_i_n_g_, _+_S_t_a_r_t_, _+_L_e_n_g_t_h_, _-_S_u_b))
- Create a substring of _S_t_r_i_n_g that starts at character _S_t_a_r_t (1
- base) and has _L_e_n_g_t_h characters. Unify this substring with _S_u_b.
-
-
- 33..2211 OOppeerraattoorrss
-
-
- oopp((_+_P_r_e_c_e_d_e_n_c_e_, _+_T_y_p_e_, _+_N_a_m_e))
- Declare _N_a_m_e to be an operator of type _T_y_p_e with precedence
- _P_r_e_c_e_d_e_n_c_e. _N_a_m_e can also be a list of names, in which case
- all elements of the list are declared to be identical operators.
- _P_r_e_c_e_d_e_n_c_e is an integer between 0 and 1200. Precedence 0 removes
- the declaration. _T_y_p_e is one of: xf, yf, xfx, xfy, yfx, yfy,
- fy or fx. The `f' indicates the position of the functor, while
- x and y indicate the position of the arguments. `y' should be
- interpreted as ``on this position a term with precedence lower or
- equal to the precedence of the functor should occur''. For `x' the
- precedence of the argument must be strictly lower. The precedence
- of a term is 0, unless its principal functor is an operator, in
- which case the precedence is the precedence of this operator. A
- term enclosed in brackets (...) has precedence 0.
-
- The predefined operators are shown in table 3.1. Note that all
- operators can be redefined by the user.
- ______________________________________________________________
- | 1200 |xfx |-->, :- |
- | 1200 | fx |:-, ?- |
- | 1150 | fx |dynamic, multifile, module_transparent, discon-|
- | | |tiguous, volatile, initialization |
- | 1100 |xfy |;, | |
-
- | 1050 |xfy |-> |
- | 1000 |xfy |, |
- | 954 |xfy |\ |
- | 900 | fy |\+, not |
- | 900 | fx |~ |
- | 700 |xfx |<, =, =.., =@=, =:=, =<, ==, =\=, >, >=, @<, |
- | | |@=<, @>, @>=, \=, \==, is |
- | 600 |xfy |: |
-
- | 500 | yfx |+, -, /\, \/, xor |
- | 500 | fx |+, -, ?, \ |
- | 400 | yfx |*, /, //, <<, >>, mod, rem |
- | 200 |xfx |** |
- |__200_|xfy__|^______________________________________________|_
-
- Table 3.1: System operators
-
-
- ccuurrrreenntt__oopp((_?_P_r_e_c_e_d_e_n_c_e_, _?_T_y_p_e_, _?_N_a_m_e))
- Succeeds when _N_a_m_e is currently defined as an operator of type _T_y_p_e
- with precedence _P_r_e_c_e_d_e_n_c_e. See also oopp//33.
-
-
- 33..2222 AArriitthhmmeettiicc
-
- Arithmetic can be divided into some special purpose integer predicates
- and a series of general predicates for floating point and integer
- arithmetic as appropriate. The integer predicates are as ``logical''
- as possible. Their usage is recommended whenever applicable, resulting
- in faster and more ``logical'' programs.
-
- The general arithmetic predicates are optionally compiled now (see
- pplleeaassee//33 and the -O command line option). Compiled arithmetic reduces
- global stack requirements and improves performance. Unfortunately
- compiled arithmetic cannot be traced, which is why it is optional.
-
- The general arithmetic predicates all handle _e_x_p_r_e_s_s_i_o_n_s. An
- expression is either a simple number or a _f_u_n_c_t_i_o_n. The arguments of a
- function are expressions. The functions are described in section 3.23.
-
-
- bbeettwweeeenn((_+_L_o_w_, _+_H_i_g_h_, _?_V_a_l_u_e))
- _L_o_w and _H_i_g_h are integers, _H_i_g_h _L_o_w. If _V_a_l_u_e is an integer,
- _L_o_w _V_a_l_u_e _H_i_g_h. When _V_a_l_u_e is a variable it is successively
- bound to all integers between _L_o_w and _H_i_g_h.
-
-
- ssuucccc((_?_I_n_t_1_, _?_I_n_t_2))
- Succeeds if _I_n_t_2= _I_n_t_1+ 1. At least one of the arguments must be
- instantiated to an integer.
-
-
- pplluuss((_?_I_n_t_1_, _?_I_n_t_2_, _?_I_n_t_3))
- Succeeds if _I_n_t_3= _I_n_t_1+_I_n_t_2. At least two of the three arguments
- must be instantiated to integers.
-
-
- _+_E_x_p_r_1 > _+_E_x_p_r_2
- Succeeds when expression _E_x_p_r_1 evaluates to a larger number than
- _E_x_p_r_2.
-
-
- _+_E_x_p_r_1 < _+_E_x_p_r_2
- Succeeds when expression _E_x_p_r_1 evaluates to a smaller number than
- _E_x_p_r_2.
-
-
- _+_E_x_p_r_1 =< _+_E_x_p_r_2
- Succeeds when expression _E_x_p_r_1 evaluates to a smaller or equal
- number to _E_x_p_r_2.
-
-
- _+_E_x_p_r_1 >= _+_E_x_p_r_2
- Succeeds when expression _E_x_p_r_1 evaluates to a larger or equal
- number to _E_x_p_r_2.
-
-
- _+_E_x_p_r_1 =\= _+_E_x_p_r_2
- Succeeds when expression _E_x_p_r_1 evaluates to a number non-equal to
- _E_x_p_r_2.
-
-
- _+_E_x_p_r_1 =:= _+_E_x_p_r_2
- Succeeds when expression _E_x_p_r_1 evaluates to a number equal to
- _E_x_p_r_2.
-
-
- _-_N_u_m_b_e_r iiss _+_E_x_p_r
- Succeeds when _N_u_m_b_e_r has successfully been unified with the
- number _E_x_p_r evaluates to. If _E_x_p_r evaluates to a float that
- can be represented using an integer (i.e. the value is integer
- and within the range that can be described by Prolog's integer
- representation), _E_x_p_r is unified with the integer value.
-
- Note that normally, iiss//22 will be used with unbound left operand.
- If equality is to be tested, =:=/2 should be used. For example:
-
- ?- 1.0 is sin(pi/2). Fails!. sin(pi/2) evaluates
- to 1.0, but iiss//22 will
- represent this as the integer
- 1, after which unify will
- fail.
-
- ?- 1.0 is float(sin(pi/2)). Succeeds, as the ffllooaatt//11
- function forces the result to
- be float.
- ?- 1.0 =:= sin(pi/2). Succeeds as expected.
-
-
- 33..2233 AArriitthhmmeettiicc FFuunnccttiioonnss
-
- Arithmetic functions are terms which are evaluated by the arithmetic
- predicates described above. SWI-Prolog tries to hide the difference
- between integer arithmetic and floating point arithmetic from the
- Prolog user. Arithmetic is done as integer arithmetic as long as
- possible and converted to floating point arithmetic whenever one of
- the arguments or the combination of them requires it. If a function
- returns a floating point value which is whole it is automatically
- transformed into an integer. There are three types of arguments to
- functions:
-
- _E_x_p_r Arbitrary expression, returning either a
- floating point value or an integer.
- _I_n_t_E_x_p_r Arbitrary expression that should evaluate into
- an integer.
- _I_n_t An integer.
-
- In case integer addition, subtraction and multiplication would lead
- to an integer overflow the operands are automatically converted to
- floating point numbers. The floating point functions (ssiinn//11, eexxpp//11,
- etc.) form a direct interface to the corresponding C library
- functions used to compile SWI-Prolog. Please refer to the C library
- documentation for details on precision, error handling, etc.
-
-
- - _+_E_x_p_r
- _R_e_s_u_l_t =-_E_x_p_r
-
-
- _+_E_x_p_r_1 + _+_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1 +_E_x_p_r_2
-
-
- _+_E_x_p_r_1 - _+_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1 -_E_x_p_r_2
-
-
- _+_E_x_p_r_1 * _+_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1_*Expr2
-
-
- _+_E_x_p_r_1 / _+_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1=_E_x_p_r_2
-
-
- _+_I_n_t_E_x_p_r_1 mmoodd _+_I_n_t_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1mod_E_x_p_r_2 (remainder of division).
-
-
- _+_I_n_t_E_x_p_r_1 rreemm _+_I_n_t_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1rem_E_x_p_r_2 (remainder of division).
-
-
- _+_I_n_t_E_x_p_r_1 // _+_I_n_t_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1 _E_x_p_r_2 (integer division).
-
-
- aabbss((_+_E_x_p_r))
- Evaluate _E_x_p_r and return the absolute value of it.
-
-
- ssiiggnn((_+_E_x_p_r))
- Evaluate to -1 if _E_x_p_r <0, 1 if _E_x_p_r >0 and 0 if _E_x_p_r =0.
-
-
- mmaaxx((_+_E_x_p_r_1_, _+_E_x_p_r_2))
- Evaluates to the largest of both _E_x_p_r_1 and _E_x_p_r_2.
-
-
- mmiinn((_+_E_x_p_r_1_, _+_E_x_p_r_2))
- Evaluates to the smallest of both _E_x_p_r_1 and _E_x_p_r_2.
-
-
- .((_+_I_n_t_, _[_]))
- A list of one element evaluates to the element. This implies
- "a" evaluates to the ASCII value of the letter `a' (97). This
- option is available for compatibility only. It will not work if
- `style_check(+string)' is active as "a" will then be transformed
- into a string object. The recommended way to specify the ASCII
- value of the letter `a' is 0'a.
-
-
- rraannddoomm((_+_I_n_t))
- Evaluates to a random integer _i for which 0 i< _I_n_t. The seed
- of this random generator is determined by the system clock when
- SWI-Prolog was started.
-
-
- rroouunndd((_+_E_x_p_r))
- Evaluates _E_x_p_r and rounds the result to the nearest integer.
-
-
- iinntteeggeerr((_+_E_x_p_r))
- Same as rroouunndd//11 (backward compatibility).
-
-
- ffllooaatt((_+_E_x_p_r))
- Translate the result to a floating point number. Normally, Prolog
- will use integers whenever possible. When used around the 2nd
- argument of iiss//22, the result will be returned as a floating point
- number. In other contexts, the operation has no effect.
-
-
- ffllooaatt__ffrraaccttiioonnaall__ppaarrtt((_+_E_x_p_r))
- Fractional part of a floating-point number. Negative if _E_x_p_r is
- negative, 0 if _E_x_p_r is integer.
-
-
- ffllooaatt__iinntteeggeerr__ppaarrtt((_+_E_x_p_r))
- Integer part of floating-point number. Negative if _E_x_p_r is
- negative, _E_x_p_r if _E_x_p_r is integer.
-
-
- ttrruunnccaattee((_+_E_x_p_r))
- Truncate _E_x_p_r to an integer. Same as ffllooaatt__iinntteeggeerr__ppaarrtt//11.
-
-
- fflloooorr((_+_E_x_p_r))
- Evaluates _E_x_p_r and returns the largest integer smaller or equal to
- the result of the evaluation.
-
-
- cceeiilliinngg((_+_E_x_p_r))
- Evaluates _E_x_p_r and returns the smallest integer larger or equal to
- the result of the evaluation.
-
-
- cceeiill((_+_E_x_p_r))
- Same as cceeiilliinngg//11 (backward compatibility).
-
-
- _+_I_n_t_E_x_p_r >> _+_I_n_t_E_x_p_r
- Bitwise shift _I_n_t_E_x_p_r_1 by _I_n_t_E_x_p_r_2 bits to the right.
-
-
- _+_I_n_t_E_x_p_r << _+_I_n_t_E_x_p_r
- Bitwise shift _I_n_t_E_x_p_r_1 by _I_n_t_E_x_p_r_2 bits to the left.
-
-
- _+_I_n_t_E_x_p_r \/ _+_I_n_t_E_x_p_r
- Bitwise `or' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2.
-
-
- _+_I_n_t_E_x_p_r /\ _+_I_n_t_E_x_p_r
- Bitwise `and' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2.
-
-
- _+_I_n_t_E_x_p_r xxoorr _+_I_n_t_E_x_p_r
- Bitwise `exclusive or' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2.
-
-
- \ _+_I_n_t_E_x_p_r
- Bitwise negation.
-
-
- ssqqrrtt((_+_E_x_p_r))
- _R_e_s_u_l_t =square root of _E_x_p_r
-
-
- ssiinn((_+_E_x_p_r))
- _R_e_s_u_l_t =sine of _E_x_p_r. _E_x_p_r is the angle in radians.
-
-
- ccooss((_+_E_x_p_r))
- _R_e_s_u_l_t =cosine of _E_x_p_r. _E_x_p_r is the angle in radians.
-
-
- ttaann((_+_E_x_p_r))
- _R_e_s_u_l_t =tangus of _E_x_p_r. _E_x_p_r is the angle in radians.
-
-
- aassiinn((_+_E_x_p_r))
- _R_e_s_u_l_t =inverse sine of _E_x_p_r. _R_e_s_u_l_t is the angle in radians.
-
-
- aaccooss((_+_E_x_p_r))
- _R_e_s_u_l_t =inverse cosine of _E_x_p_r. _R_e_s_u_l_t is the angle in radians.
-
-
- aattaann((_+_E_x_p_r))
- _R_e_s_u_l_t =inverse tangus of _E_x_p_r. _R_e_s_u_l_t is the angle in radians.
-
-
- aattaann((_+_Y_E_x_p_r_, _+_X_E_x_p_r))
- _R_e_s_u_l_t = inverse tangus of _Y_E_x_p_r / _X_E_x_p_r. _R_e_s_u_l_t is the angle in
- radians. The return value is in the range [-pi:::pi]. Used to
- convert between rectangular and polar coordinate system.
-
-
- lloogg((_+_E_x_p_r))
- _R_e_s_u_l_t =natural logarithm of _E_x_p_r
-
-
- lloogg1100((_+_E_x_p_r))
- _R_e_s_u_l_t =10 base logarithm of _E_x_p_r
-
-
- eexxpp((_+_E_x_p_r))
- _R_e_s_u_l_t =e to the power _E_x_p_r
-
-
- _+_E_x_p_r_1 ** _+_E_x_p_r_2
- _R_e_s_u_l_t =_E_x_p_r_1 to the power _E_x_p_r_2
-
-
- _+_E_x_p_r_1 ^ _+_E_x_p_r_2
- Same as **/2. (backward compatibility).
-
-
- ppii
- Evaluates to the mathematical constant pi (3.141593).
-
-
- ee
- Evaluates to the mathematical constant e (2.718282).
-
-
- ccppuuttiimmee
- Evaluates to a floating point number expressing the cpu time (in
- seconds) used by Prolog up till now. See also ssttaattiissttiiccss//22 and
- ttiimmee//11.
-
-
- 33..2244 AAddddiinngg AArriitthhmmeettiicc FFuunnccttiioonnss
-
- Prolog predicates can be given the role of arithmetic function. The
- last argument is used to return the result, the arguments before
- the last are the inputs. Arithmetic functions are added using the
- predicate aarriitthhmmeettiicc__ffuunnccttiioonn//11, which takes the head as its argument.
- Arithmetic functions are module sensitive, that is they are only
- visible from the module in which the function is defined and declared.
- Global arithmetic functions should be defined and registered from
- module user. Global definitions can be overruled locally in modules.
- The builtin functions described above can be redefined as well.
-
-
- aarriitthhmmeettiicc__ffuunnccttiioonn((_+_H_e_a_d))
- Register a Prolog predicate as an arithmetic function (see iiss//22,
- >//22 , etc.). The Prolog predicate should have one more argument
- than specified by _H_e_a_d, which it either a term _N_a_m_e_/_A_r_i_t_y, an atom
- or a complex term. This last argument is an unbound variable at
- call time and should be instantiated to an integer or floating
- point number. The other arguments are the parameters. This
- predicate is module sensitive and will declare the arithmetic
- function only for the context module, unless declared from module
- user. Example:
-
- 1 ?- [user].
- :- arithmetic_function(mean/2).
-
- mean(A, B, C) :-
- C is (A+B)/2.
- user compiled, 0.07 sec, 440 bytes.
-
- Yes
- 2 ?- A is mean(4, 5).
-
- A = 4.500000
-
-
- ccuurrrreenntt__aarriitthhmmeettiicc__ffuunnccttiioonn((_?_H_e_a_d))
- Successively unifies all arithmetic functions that are visible from
- the context module with _H_e_a_d.
-
-
- 33..2255 LLiisstt MMaanniippuullaattiioonn
-
-
- iiss__lliisstt((_+_T_e_r_m))
- Succeeds if _T_e_r_m is bound to the empty list ([]) or a term with
- functor `.' and arity 2.
-
-
- pprrooppeerr__lliisstt((_+_T_e_r_m))
- Equivalent to iiss__lliisstt//11, but also requires the tail of the list to
- be a list (recursively). Examples:
-
- is_list([x|A]) % true
- proper_list([x|A]) % false
-
-
- aappppeenndd((_?_L_i_s_t_1_, _?_L_i_s_t_2_, _?_L_i_s_t_3))
- Succeeds when _L_i_s_t_3 unifies with the concatenation of _L_i_s_t_1 and
- _L_i_s_t_2. The predicate can be used with any instantiation pattern
- (even three variables).
-
-
- mmeemmbbeerr((_?_E_l_e_m_, _?_L_i_s_t))
- Succeeds when _E_l_e_m can be unified with one of the members of _L_i_s_t.
- The predicate can be used with any instantiation pattern.
-
-
- mmeemmbbeerrcchhkk((_?_E_l_e_m_, _+_L_i_s_t))
- Equivalent to mmeemmbbeerr//22, but leaves no choice point.
-
-
- ddeelleettee((_+_L_i_s_t_1_, _?_E_l_e_m_, _?_L_i_s_t_2))
- Delete all members of _L_i_s_t_1 that simultaneously unify with _E_l_e_m and
- unify the result with _L_i_s_t_2.
-
-
- sseelleecctt((_?_L_i_s_t_1_, _?_E_l_e_m_, _?_L_i_s_t_2))
- Select an element of _L_i_s_t_1 that unifies with _E_l_e_m. _L_i_s_t_2 is
- unified with the list remaining from _L_i_s_t_1 after deleting the
- selected element. Normally used with the instantiation pattern
- _+_L_i_s_t_1_, _-_E_l_e_m_, _-_L_i_s_t_2, but can also be used to insert an element in
- a list using _-_L_i_s_t_1_, _+_E_l_e_m_, _+_L_i_s_t_2.
-
-
- nntthh00((_?_I_n_d_e_x_, _?_L_i_s_t_, _?_E_l_e_m))
- Succeeds when the _I_n_d_e_x-th element of _L_i_s_t unifies with _E_l_e_m.
- Counting starts at 0.
-
-
- nntthh11((_?_I_n_d_e_x_, _?_L_i_s_t_, _?_E_l_e_m))
- Succeeds when the _I_n_d_e_x-th element of _L_i_s_t unifies with _E_l_e_m.
- Counting starts at 1.
-
-
- llaasstt((_?_E_l_e_m_, _?_L_i_s_t))
- Succeeds if _E_l_e_m unifies with the last element of _L_i_s_t.
-
-
- rreevveerrssee((_+_L_i_s_t_1_, _-_L_i_s_t_2))
- Reverse the order of the elements in _L_i_s_t_1 and unify the result
- with the elements of _L_i_s_t_2.
-
-
- ffllaatttteenn((_+_L_i_s_t_1_, _-_L_i_s_t_2))
- Transform _L_i_s_t_1, possibly holding lists as elements into a `flat'
- list by replacing each list with its elements (recursively). Unify
- the resulting flat list with _L_i_s_t_2. Example:
-
- ?- flatten([a, [b, [c, d], e]], X).
-
- X = [a, b, c, d, e]
-
-
- lleennggtthh((_?_L_i_s_t_, _?_I_n_t))
- Succeeds if _I_n_t represents the number of elements of list _L_i_s_t.
- Can be used to create a list holding only variables.
-
-
- mmeerrggee((_+_L_i_s_t_1_, _+_L_i_s_t_2_, _-_L_i_s_t_3))
- _L_i_s_t_1 and _L_i_s_t_2 are lists, sorted to the standard order of terms
- (see section 3.5). _L_i_s_t_3 will be unified with an ordered list
- holding both the elements of _L_i_s_t_1 and _L_i_s_t_2. Duplicates are nnoott
- removed.
-
-
- 33..2266 SSeett MMaanniippuullaattiioonn
-
-
- iiss__sseett((_+_S_e_t))
- Succeeds if _S_e_t is a proper list (see pprrooppeerr__lliisstt//11) without
- duplicates.
-
-
- lliisstt__ttoo__sseett((_+_L_i_s_t_, _-_S_e_t))
- Unifies _S_e_t with a list holding the same elements as _L_i_s_t in
- the same order. If _l_i_s_t contains duplicates, only the first is
- retained. See also ssoorrtt//22. Example:
-
- ?- list_to_set([a,b,a], X)
-
- X = [a,b]
-
-
- iinntteerrsseeccttiioonn((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3))
- Succeeds if _S_e_t_3 unifies with the intersection of _S_e_t_1 and _S_e_t_2.
- _S_e_t_1 and _S_e_t_2 are lists without duplicates. They need not be
- ordered.
-
-
- ssuubbttrraacctt((_+_S_e_t_, _+_D_e_l_e_t_e_, _-_R_e_s_u_l_t))
- Delete all elements of set `Delete' from `Set' and unify the
- resulting set with `Result'.
-
-
- uunniioonn((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3))
- Succeeds if _S_e_t_3 unifies with the union of _S_e_t_1 and _S_e_t_2. _S_e_t_1 and
- _S_e_t_2 are lists without duplicates. They need not be ordered.
-
-
- ssuubbsseett((_+_S_u_b_s_e_t_, _+_S_e_t))
- Succeeds if all elements of _S_u_b_s_e_t are elements of _S_e_t as well.
-
-
- mmeerrggee__sseett((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3))
- _S_e_t_1 and _S_e_t_2 are lists without duplicates, sorted to the standard
- order of terms. _S_e_t_3 is unified with an ordered list without
- duplicates holding the union of the elements of _S_e_t_1 and _S_e_t_2.
-
-
- 33..2277 SSoorrttiinngg LLiissttss
-
-
- ssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
- Succeeds if _S_o_r_t_e_d can be unified with a list holding the elements
- of _L_i_s_t, sorted to the standard order of terms (see section 3.5).
- Duplicates are removed. Implemented by translating the input list
- into a temporary array, calling the C-library function qqssoorrtt((3))
- using PPLL__ccoommppaarree(()) for comparing the elements, after which the
- result is translated into the result list.
-
-
- mmssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
- Equivalent to ssoorrtt//22, but does not remove duplicates.
-
-
- kkeeyyssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
- _L_i_s_t is a list of Key-Value pairs (e.g. terms of the functor
- `-' with arity 2). kkeeyyssoorrtt//22 sorts _L_i_s_t like mmssoorrtt//22, but
- only compares the keys. Can be used to sort terms not on
- standard order, but on any criterion that can be expressed on a
- multi-dimensional scale. Sorting on more than one criterion can be
- done using terms as keys, putting the first criterion as argument
- 1, the second as argument 2, etc. The order of multiple elements
- that have the same _K_e_y is not changed.
-
-
- pprreeddssoorrtt((_+_P_r_e_d_, _+_L_i_s_t_, _-_S_o_r_t_e_d))
- Sorts similar to mmssoorrtt//22, but determines the order of two terms by
- applying _P_r_e_d to pairs of elements from _L_i_s_t (see aappppllyy//22). The
- predicate should succeed if the first element should be before the
- second.
-
-
- 33..2288 FFiinnddiinngg aallll SSoolluuttiioonnss ttoo aa GGooaall
-
-
- ffiinnddaallll((_+_V_a_r_, _+_G_o_a_l_, _-_B_a_g))
- Creates a list of the instantiations _V_a_r gets successively on
- backtracking over _G_o_a_l and unifies the result with _B_a_g. Succeeds
- with an empty list if _G_o_a_l has no solutions. ffiinnddaallll//33 is
- equivalent to bbaaggooff//33 with all free variables bound with the
- existence operator (^), except that bbaaggooff//33 fails when goal has no
- solutions.
-
-
- bbaaggooff((_+_V_a_r_, _+_G_o_a_l_, _-_B_a_g))
- Unify _B_a_g with the alternatives of _V_a_r, if _G_o_a_l has free variables
- besides the one sharing with _V_a_r bagof will backtrack over the
- alternatives of these free variables, unifying _B_a_g with the
- corresponding alternatives of _V_a_r. The construct +Var^Goal tells
- bagof not to bind _V_a_r in _G_o_a_l. bbaaggooff//33 fails if _G_o_a_l has no
- solutions.
-
- The example below illustrates bbaaggooff//33 and the ^ operator. The
- variable bindings are printed together on one line to save paper.
-
- 2 ?- listing(foo).
-
- foo(a, b, c).
- foo(a, b, d).
- foo(b, c, e).
- foo(b, c, f).
- foo(c, c, g).
-
- Yes
- 3 ?- bagof(C, foo(A, B, C), Cs).
-
- A = a, B = b, C = G308, Cs = [c, d] ;
- A = b, B = c, C = G308, Cs = [e, f] ;
- A = c, B = c, C = G308, Cs = [g] ;
-
- No
- 4 ?- bagof(C, A^foo(A, B, C), Cs).
-
- A = G324, B = b, C = G326, Cs = [c, d] ;
- A = G324, B = c, C = G326, Cs = [e, f, g] ;
-
- No
- 5 ?-
-
-
- sseettooff((_+_V_a_r_, _+_G_o_a_l_, _-_S_e_t))
- Equivalent to bbaaggooff//33, but sorts the result using ssoorrtt//22 to get a
- sorted list of alternatives without duplicates.
-
-
- 33..2299 IInnvvookkiinngg PPrreeddiiccaatteess oonn aallll MMeemmbbeerrss ooff aa LLiisstt
-
- All the predicates in this section call a predicate on all members of
- a list or until the predicate called fails. The predicate is called
- via aappppllyy//22, which implies common arguments can be put in front of the
- arguments obtained from the list(s). For example:
-
- ?- maplist(plus(1), [0, 1, 2], X).
-
- X = [1, 2, 3]
-
- we will phrase this as ``_P_r_e_d_i_c_a_t_e is applied on ...''
-
-
- cchheecckklliisstt((_+_P_r_e_d_, _+_L_i_s_t))
- _P_r_e_d is applied successively on each element of _L_i_s_t until the end
- of the list or _P_r_e_d fails. In the latter case the cchheecckklliisstt//22
- fails.
-
-
- mmaapplliisstt((_+_P_r_e_d_, _?_L_i_s_t_1_, _?_L_i_s_t_2))
- Apply _P_r_e_d on all successive pairs of elements from _L_i_s_t_1 and
- _L_i_s_t_2. Fails if _P_r_e_d can not be applied to a pair. See the
- example above.
-
-
- ssuubblliisstt((_+_P_r_e_d_, _+_L_i_s_t_1_, _?_L_i_s_t_2))
- Unify _L_i_s_t_2 with a list of all elements of _L_i_s_t_1 to which _P_r_e_d
- applies.
-
-
- 33..3300 FFoorraallll
-
-
- ffoorraallll((_+_C_o_n_d_, _+_A_c_t_i_o_n))
- For all alternative bindings of _C_o_n_d _A_c_t_i_o_n can be proven. The
- example verifies that all arithmetic statements in the list _L are
- correct. It does not say which is wrong if one proves wrong.
-
- ?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]),
- Result =:= Formula).
-
-
- 33..3311 FFoorrmmaatttteedd WWrriittee
-
- The current version of SWI-Prolog provides two formatted write
- predicates. The first is wwrriitteeff//[[11,,22]], which is compatible with
- Edinburgh C-Prolog. The second is ffoorrmmaatt//[[11,,22]], which is compatible
- with Quintus Prolog. We hope the Prolog community will once define
- a standard formatted write predicate. If you want performance use
- ffoorrmmaatt//[[11,,22]] as this predicate is defined in C. Otherwise compatibility
- reasons might tell you which predicate to use.
-
-
- 33..3311..11 WWrriitteeff
-
-
- wwrriittee__llnn((_+_T_e_r_m))
- Equivalent to write(Term), nl.
-
-
- wwrriitteeff((_+_A_t_o_m))
- Equivalent to writef(Atom, []).
-
-
- wwrriitteeff((_+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
- Formatted write. _F_o_r_m_a_t is an atom whose characters will
- be printed. _F_o_r_m_a_t may contain certain special character
- sequences which specify certain formatting and substitution
- actions. _A_r_g_u_m_e_n_t_s then provides all the terms required to be
- output.
-
- Escape sequences to generate a single special character:
-
- __________________________________________________
- | \n |Output a nemline character (see also |
- | |nnll//[[00,,11]]) |
- | \l |Output a line separator (same as \n) |
-
- | \r |Output a carriage-return character |
- | |(ASCII 13) |
- | \t |Output the ASCII character TAB (9) |
- | \\ |The character \ is output |
- | \% |The character % is output |
- | \nnn |where <_n_n_n> is an integer (1-3 digits) |
- | |the character with ASCII code <_n_n_n> is |
-
- |______|output_(NB_:_<_n_n_n>_is_read_as_ddeecciimmaall)____|
-
- Note that \l, \\bnfmeta{nnn} and \\ are interpreted differently
- when character-escapes are in effect. See section 2.11.1.1.
-
- Escape sequences to include arguments from _A_r_g_u_m_e_n_t_s. Each time
- a % escape sequence is found in _F_o_r_m_a_t the next argument from
- _A_r_g_u_m_e_n_t_s is formatted according to the specification.
-
- _________________________________________________%t
-
- | %w pprriinntt//11 the next item (mnemonic: term) | |
-
- | %q |wwrriittee//11the next item |
-
- | %d |wwrriitteeqq//11the next item |
-
- | %p |ddiissppllaayy//11the next item |
-
- | |pprriinntt//11the next item (identical to %t) |
- | %n |Put the next item as a character (i.e.|
- | |it is an ASCII value) |
- | %r |Write the next item N times where N is|
- | |the second item (an integer) |
-
- | %s |Write the next item as a String (so it|
- | |must be a list of characters) |
- | %f |Perform a ttttyyfflluusshh//00 (no items used) |
- | %Nc |Write the next item Centered in N |
- | |columns. |
- | %Nl |Write the next item Left justified in N |
- | |columns. |
-
- | %Nr |Write the next item Right justified in N |
- | |columns. N is a decimal number with at|
- | |least one digit. The item must be an|
- |_____|atom,_integer,_float_or_string.__________|_
-
-
- sswwrriitteeff((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
- Equivalent to wwrriitteeff//22, but ``writes'' the result on _S_t_r_i_n_g instead
- of the current output stream. Example:
-
- ?- swritef(S, '%15L%w', ['Hello', 'World']).
-
- S = "Hello World"
-
-
- sswwrriitteeff((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t))
- Equivalent to swritef(String, Format, []).
-
-
- 33..3311..22 FFoorrmmaatt
-
-
- ffoorrmmaatt((_+_F_o_r_m_a_t))
- Defined as `format(Format) :- format(Format, []).'
-
-
- ffoorrmmaatt((_+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
- _F_o_r_m_a_t is an atom, list of ASCII values, or a Prolog
- string. _A_r_g_u_m_e_n_t_s provides the arguments required by the format
- specification. If only one argument is required and this is not
- a list of ASCII values the argument need not be put in a list.
- Otherwise the arguments are put in a list.
-
- Special sequences start with the tilde (~), followed by an optional
- numeric argument, followed by a character describing the action to
- be undertaken. A numeric argument is either a sequence of digits,
- representing a positive decimal number, a sequence `<_c_h_a_r_a_c_t_e_r>,
- representing the ASCII value of the character (only useful for ~t)
- or a asterisk (*), in when the numeric argument is taken from the
- next argument of the argument list, which should be a positive
- integer. Actions are:
-
- ~ Output the tilde itself.
-
- a Output the next argument, which should be an atom. This
- option is equivalent to ww. Compatibility reasons only.
-
- c Output the next argument as an ASCII value. This argument
- should be an integer in the range [0, ..., 255] (including 0
- and 255).
-
- d Output next argument as a decimal number. It should be
- an integer. If a numeric argument is specified a dot is
- inserted _a_r_g_u_m_e_n_t positions from the right (useful for doing
- fixed point arithmetic with integers, such as handling amounts
- of money).
-
- D Same as dd, but makes large values easier to read by inserting
- a comma every three digits left to the dot or right.
-
- e Output next argument as a floating point number in exponential
- notation. The numeric argument specifies the precision.
- Default is 6 digits. Exact representation depends on the C
- library function printf(). This function is invoked with the
- format %.<_p_r_e_c_i_s_i_o_n>e.
-
- E Equivalent to ee, but outputs a capital E to indicate the
- exponent.
-
- f Floating point in non-exponential notation. See C library
- function printf().
-
- g Floating point in ee or ff notation, whichever is shorter.
-
- G Floating point in EE or ff notation, whichever is shorter.
-
- i Ignore next argument of the argument list. Produces no
- output.
-
- k Give the next argument to ddiissppllaayyqq//11 (canonical write).
-
- n Output a newline character.
-
- N Only output a newline if the last character output on this
- stream was not a newline. Not properly implemented yet.
-
- p Give the next argument to pprriinntt//11.
-
- q Give the next argument to wwrriitteeqq//11.
-
- r Print integer in radix the numeric argument notation. Thus
- ~16r prints its argument hexadecimal. The argument should be
- in the range [2; :::;36]. Lower case letters are used for digits
- above 9.
-
- R Same as rr, but uses upper case letters for digits above 9.
-
- s Output a string of ASCII characters or a string (see ssttrriinngg//11
- and section 3.20) from the next argument.
-
- t All remaining space between 2 tabs tops is distributed equally
- over ~t statements between the tabs tops. This space is
- padded with spaces by default. If an argument is supplied
- this is taken to be the ASCII value of the character used for
- padding. This can be used to do left or right alignment,
- centering, distributing, etc. See also ~| and ~+ to set tab
- stops. A tabs top is assumed at the start of each line.
-
- | Set a tabs top on the current position. If an argument is
- supplied set a tabs top on the position of that argument.
- This will cause all ~t's to be distributed between the
- previous and this tabs top.
-
- + Set a tabs top relative to the current position. Further the
- same as ~|.
-
- w Give the next argument to wwrriittee//11.
-
- Example:
-
- simple_statistics :-
- <obtain statistics> % left to the user
- format('~tStatistics~t~72|~n~n'),
- format('Runtime: ~`.t ~2f~34| Inferences: ~`.t ~D~72|~n',
- [RunT, Inf]),
- ....
-
- Will output
-
- Statistics
-
- Runtime: .................. 3.45 Inferences: .......... 60,345
-
-
- ffoorrmmaatt((_+_S_t_r_e_a_m_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
- As ffoorrmmaatt//22, but write the output on the given _S_t_r_e_a_m.
-
-
- ssffoorrmmaatt((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
- Equivalent to ffoorrmmaatt//22, but ``writes'' the result on _S_t_r_i_n_g instead
- of the current output stream. Example:
-
- ?- sformat(S, '~w~t~15|~w', ['Hello', 'World']).
-
- S = "Hello World"
-
-
- ssffoorrmmaatt((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t))
- Equivalent to `sformat(String, Format, []).'
-
-
- 33..3311..33 PPrrooggrraammmmiinngg FFoorrmmaatt
-
-
- ffoorrmmaatt__pprreeddiiccaattee((_+_C_h_a_r_, _+_H_e_a_d))
- If a sequence ~c (tilde, followed by some character) is found, the
- format derivatives will first check whether the user has defined a
- predicate to handle the format. If not, the built in formatting
- rules described above are used. _C_h_a_r is either an ascii value,
- or a one character atom, specifying the letter to be (re)defined.
- _H_e_a_d is a term, whose name and arity are used to determine the
- predicate to call for the redefined formatting character. The
- first argument to the predicate is the numeric argument of the
- format command, or the atom default if no argument is specified.
- The remaining arguments are filled from the argument list. The
- example below redefines ~n to produce _A_r_g times return followed by
- linefeed (so a (Grr.) DOS machine is happy with the output).
-
- :- format_predicate(n, dos_newline(_Arg)).
-
- dos_newline(Arg) :-
- between(1, Ar, _), put(13), put(10), fail ; true.
-
-
- 33..3322 TTeerrmmiinnaall CCoonnttrrooll
-
- The following predicates form a simple access mechanism to the
- Unix termcap library to provide terminal independent I/O for screen
- terminals. The library package library(tty) builds on top of these
- predicates.
-
-
- ttttyy__ggeett__ccaappaabbiilliittyy((_+_N_a_m_e_, _+_T_y_p_e_, _-_R_e_s_u_l_t))
- Get the capability named _N_a_m_e from the termcap library. See
- termcap(5) for the capability names. _T_y_p_e specifies the type of
- the expected result, and is one of string, number or bool. String
- results are returned as an atom, number result as an integer and
- bool results as the atom on or off. If an option cannot be found
- this predicate fails silently. The results are only computed once.
- Successive queries on the same capability are fast.
-
-
- ttttyy__ggoottoo((_+_X_, _+_Y))
- Goto position (_X, _Y) on the screen. Note that the predicates
- lliinnee__ccoouunntt//22 and lliinnee__ppoossiittiioonn//22 will not have a well defined
- behaviour while using this predicate.
-
-
- ttttyy__ppuutt((_+_A_t_o_m_, _+_L_i_n_e_s))
- Put an atom via the termcap library function tputs(). This
- function decodes padding information in the strings returned by
- ttttyy__ggeett__ccaappaabbiilliittyy//33 and should be used to output these strings.
- _L_i_n_e_s is the number of lines affected by the operation, or 1 if not
- applicable (as in almost all cases).
-
-
- sseett__ttttyy((_-_O_l_d_S_t_r_e_a_m_, _+_N_e_w_S_t_r_e_a_m))
- Set the output stream, used by ttttyy__ppuutt//22 and ttttyy__ggoottoo//22 to a
- specific stream. Default is user_output.
-
-
- 33..3333 OOppeerraattiinngg SSyysstteemm IInntteerraaccttiioonn
-
-
- sshheellll((_+_C_o_m_m_a_n_d_, _-_S_t_a_t_u_s))
- Execute _C_o_m_m_a_n_d on the operating system. _C_o_m_m_a_n_d is given to the
- Bourne shell (/bin/sh). _S_t_a_t_u_s is unified with the exit status of
- the command.
-
- On _W_i_n_3_2 systems, sshheellll//[[11,,22]] executes the command using the
- CreateProcess() API and waits for the command to terminate. If the
- command ends with a & sign, the command is handed to the WinExec()
- API, which does not wait for the new task to terminate. See also
- wwiinn__eexxeecc//22.
-
-
- sshheellll((_+_C_o_m_m_a_n_d))
- Equivalent to `shell(Command, 0)'.
-
-
- sshheellll
- Start an interactive Unix shell. Default is /bin/sh, the
- environment variable SHELL overrides this default. Not available
- for Win32 platforms.
-
-
- wwiinn__eexxeecc((_+_C_o_m_m_a_n_d_, _+_S_h_o_w))
- Win32 systems only. Spawns a Windows task without waiting for
- its completion. _S_h_o_w is either iconic or normal and dictates the
- initial status of the window. The iconic option is notably handy
- to start (DDE) servers.
-
-
- ggeetteennvv((_+_N_a_m_e_, _-_V_a_l_u_e))
- Get Unix environment variable (see csh(1) and sh(1)). Fails if the
- variable does not exist.
-
-
- sseetteennvv((_+_N_a_m_e_, _+_V_a_l_u_e))
- Set Unix environment variable. _N_a_m_e and _V_a_l_u_e should be
- instantiated to atoms or integers. The environment variable will
- be passed to sshheellll//[[00--22]] and can be requested using ggeetteennvv//22.
-
-
- uunnsseetteennvv((_+_N_a_m_e))
- Remove Unix environment variable from the environment.
-
-
- ggeett__ttiimmee((_-_T_i_m_e))
- Return the number of seconds that elapsed since the epoch of Unix,
- 1 January 1970, 0 hours. _T_i_m_e is a floating point number. Its
- granularity is system dependent. On sun, this is 1/60 of a second.
-
-
- ccoonnvveerrtt__ttiimmee((_+_T_i_m_e_, _-_Y_e_a_r_, _-_M_o_n_t_h_, _-_D_a_y_, _-_H_o_u_r_, _-_M_i_n_u_t_e_, _-_S_e_c_o_n_d_, _-_M_i_l_l_i_S_e_c_o_n_d_s))
-
- Convert a time stamp, provided by ggeett__ttiimmee//11, ttiimmee__ffiillee//22,
- etc. _Y_e_a_r is unified with the year, _M_o_n_t_h with the month number
- (January is 1), _D_a_y with the day of the month (starting with 1),
- _H_o_u_r with the hour of the day (0--23), _M_i_n_u_t_e with the minute
- (0--59). _S_e_c_o_n_d with the second (0--59) and _M_i_l_l_i_S_e_c_o_n_d with the
- milliseconds (0--999). Note that the latter might not be accurate
- or might always be 0, depending on the timing capabilities of the
- system.
-
-
- 33..3344 FFiillee SSyysstteemm IInntteerraaccttiioonn
-
-
- aacccceessss__ffiillee((_+_F_i_l_e_, _+_M_o_d_e))
- Succeeds if _F_i_l_e exists and can be accessed by this prolog process
- under mode _M_o_d_e. _M_o_d_e is one of the atoms read, write, append,
- exist, none or execute. _F_i_l_e may also be the name of a directory.
- Fails silently otherwise. access_file(File, none)simply succeeds
- without testing anything.
-
- If `Mode' is write or append, this predicate also succeeds if the
- file does not exist and the user has write-access to the directory
- of the specified location.
-
-
- eexxiissttss__ffiillee((_+_F_i_l_e))
- Succeeds when _F_i_l_e exists. This does not imply the user has read
- and/or write permission for the file.
-
-
- ffiillee__ddiirreeccttoorryy__nnaammee((_+_F_i_l_e_, _-_D_i_r_e_c_t_o_r_y))
- Extracts the directory-part of _F_i_l_e. The resulting _D_i_r_e_c_t_o_r_y name
- ends with the directory separator character /. If _F_i_l_e is an atom
- that does not contain any directory separator characters, the empty
- atom '' is returned. See also ffiillee__bbaassee__nnaammee//22.
-
-
- ffiillee__bbaassee__nnaammee((_+_F_i_l_e_, _-_B_a_s_e_N_a_m_e))
- Extracts the filename part from a path specification. If _F_i_l_e does
- not contain any directory separators, _F_i_l_e is returned.
-
-
- ssaammee__ffiillee((_+_F_i_l_e_1_, _+_F_i_l_e_2))
- Succeeds if both filenames refer to the same physical file. That
- is, if _F_i_l_e_1 and _F_i_l_e_2 are the same string or both names exist
- and point to the same file (due to hard or symbolic links and/or
- relative vs. absolute paths).
-
-
- eexxiissttss__ddiirreeccttoorryy((_+_D_i_r_e_c_t_o_r_y))
- Succeeds if _D_i_r_e_c_t_o_r_y exists. This does not imply the user has
- read, search and or write permission for the directory.
-
-
- ddeelleettee__ffiillee((_+_F_i_l_e))
- Unlink _F_i_l_e from the Unix file system.
-
-
- rreennaammee__ffiillee((_+_F_i_l_e_1_, _+_F_i_l_e_2))
- Rename _F_i_l_e_1 into _F_i_l_e_2. Currently files cannot be moved across
- devices.
-
-
- ssiizzee__ffiillee((_+_F_i_l_e_, _-_S_i_z_e))
- Unify _S_i_z_e with the size of _F_i_l_e in characters.
-
-
- ttiimmee__ffiillee((_+_F_i_l_e_, _-_T_i_m_e))
- Unify the last modification time of _F_i_l_e with _T_i_m_e. _T_i_m_e is a
- floating point number expressing the seconds elapsed since Jan 1,
- 1970.
-
-
- aabbssoolluuttee__ffiillee__nnaammee((_+_F_i_l_e_, _-_A_b_s_o_l_u_t_e))
- Expand Unix file specification into an absolute path. User home
- directory expansion (~ and ~<_u_s_e_r>) and variable expansion is done.
- The absolute path is canonised: references to . and .. are
- deleted. SWI-Prolog uses absolute file names to register source
- files independent of the current working directory. See also
- aabbssoolluuttee__ffiillee__nnaammee//33.
-
-
- aabbssoolluuttee__ffiillee__nnaammee((_+_S_p_e_c_, _+_O_p_t_i_o_n_s_, _-_A_b_s_o_l_u_t_e))
- Converts the given file specification into an absolute path.
- _O_p_t_i_o_n is a list of options to guide the conformation process:
-
- eexxtteennssiioonnss((_L_i_s_t_O_f_E_x_t_e_n_s_i_o_n_s))
- List of file-extensions to try. Default is ''. For each
- extension, aabbssoolluuttee__ffiillee__nnaammee//33will first add the extension and
- then verify the conditions imposed by the other options. If
- the condition fails, the next extension of the list is tried.
- Extensions may be specified both as ..ext or plain ext.
-
- aacccceessss((_M_o_d_e))
- Imposes the condition access_file(_F_i_l_e, _M_o_d_e). _M_o_d_e is on of
- read, write, append, exist or none. See also aacccceessss__ffiillee//22.
-
- ffiillee__ttyyppee((_T_y_p_e))
- Defines extensions. Current mapping: txt implies [''],
- prolog implies ['.pl', ''], executable implies ['.so', ''],
- qlf implies ['.qlf', ''] and directory implies [''].
-
- ffiillee__eerrrroorrss((_f_a_i_l_/_t_r_u_e))
- Report if the path cannot be resolved or be silent. The
- default is to stay silent.
-
- ssoolluuttiioonnss((_f_i_r_s_t_/_a_l_l))
- If first (default), the predicates leaves no choice-point.
- Otherwise a choice-point will be left and backtracking may
- yield more solutions.
-
-
- iiss__aabbssoolluuttee__ffiillee__nnaammee((_+_F_i_l_e))
- True if _F_i_l_e specifies and absolute path-name. On Unix systems,
- this implies the path starts with a `/'. For Microsoft
- based systems this implies the path starts with <_l_e_t_t_e_r>:.
- This predicate is intended to provide platform-independent
- checking for absolute paths. See also aabbssoolluuttee__ffiillee__nnaammee//22 and
- pprroolloogg__ttoo__ooss__ffiilleennaammee//22.
-
-
- ffiillee__nnaammee__eexxtteennssiioonn((_?_B_a_s_e_, _?_E_x_t_e_n_s_i_o_n_, _?_N_a_m_e))
- This predicate is used to add, remove or test filename extensions.
- The main reason for its introduction is to deal with different
- filename properties in a portable manner. If the file system
- is case-insensitive, testing for an extension will be done
- case-insensitive too. _E_x_t_e_n_s_i_o_n may be specified with or without a
- leading dot (.). If an _E_x_t_e_n_s_i_o_n is generated, it will not have a
- leading dot.
-
-
- eexxppaanndd__ffiillee__nnaammee((_+_W_i_l_d_C_a_r_d_, _-_L_i_s_t))
- Unify _L_i_s_t with a sorted list of files or directories matching
- _W_i_l_d_C_a_r_d. The normal Unix wildcard constructs `?', `*', `[...]'
- and `{...}' are recognised. The interpretation of `{...}' is
- interpreted slightly different from the C shell (csh(1)). The
- comma separated argument can be arbitrary patterns, including
- `{...}' patterns. The empty pattern is legal as well: `{.pl,}'
- matches either `.pl' or the empty string.
-
-
- pprroolloogg__ttoo__ooss__ffiilleennaammee((_?_P_r_o_l_o_g_P_a_t_h_, _?_O_s_P_a_t_h))
- Converts between the internal Prolog pathname conventions and the
- operating-system pathname conventions. The internal conventions
- are Unix and this predicates is equivalent to =/2 (unify) on Unix
- systems. On DOS systems it will change the directory-separator,
- limit the filename length map dots, except for the last one, onto
- underscores.
-
-
- rreeaadd__lliinnkk((_+_F_i_l_e_, _-_L_i_n_k_, _-_T_a_r_g_e_t))
- If _F_i_l_e points to a symbolic link, unify _L_i_n_k with the value of the
- link and _T_a_r_g_e_t to the file the link is pointing to. _T_a_r_g_e_t points
- to a file, directory or non-existing entry in the file system, but
- never to a link. Fails if _F_i_l_e is not a link. Fails always on
- systems that do not support symbolic links.
-
-
- ttmmpp__ffiillee((_+_B_a_s_e_, _-_T_m_p_N_a_m_e))
- Create a name for a temporary file. _B_a_s_e is an identifier for the
- category of file. The _T_m_p_N_a_m_e is guaranteed to be unique. If the
- system halts, it will automatically remove all created temporary
- files.
-
-
- cchhddiirr((_+_P_a_t_h))
- Change working directory to _P_a_t_h.
-
-
- 33..3355 UUsseerr TToopplleevveell MMaanniippuullaattiioonn
-
-
- bbrreeaakk
- Recursively start a new Prolog top level. This Prolog top level
- has its own stacks, but shares the heap with all break environments
- and the top level. Debugging is switched off on entering a break
- and restored on leaving one. The break environment is terminated
- by typing the system's end-of-file character (control-D). If the
- -t toplevel command line option is given this goal is started
- instead of entering the default interactive top level (pprroolloogg//00).
-
-
- aabboorrtt
- Abort the Prolog execution and start a new top level. If the
- -t toplevel command line options is given this goal is started
- instead of entering the default interactive top level. Break
- environments are aborted as well. All open files except for the
- terminal related files are closed. The input- and output stream
- again refers to _u_s_e_r.
-
-
- hhaalltt
- Terminate Prolog execution. Open files are closed and if the
- command line option -tty is not active the terminal status (see
- Unix stty(1)) is restored. Hooks may be registered both in Prolog
- and in foreign code. Prolog hooks are registered using aatt__hhaalltt//11.
- hhaalltt//00 is equivalent to halt(0).
-
-
- hhaalltt((_+_S_t_a_t_u_s))
- Terminate Prolog execution with given status. Status is an
- integer. See also hhaalltt//00.
-
-
- pprroolloogg
- This goal starts the default interactive top level. Queries are
- read from the stream user_input. See also the history feature
- (ffeeaattuurree//22). The pprroolloogg//00 predicate is terminated (succeeds) by
- typing the end-of-file character (Unix: control-D).
-
- The following two hooks allow for expanding queries and handling the
- result of a query. These hooks are used by the toplevel variable
- expansion mechanism described in section 2.5.
-
-
- eexxppaanndd__qquueerryy((_+_Q_u_e_r_y_, _-_E_x_p_a_n_d_e_d_, _+_B_i_n_d_i_n_g_s_, _-_E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s))
- Hook in module user, normally not defined. _Q_u_e_r_y and _B_i_n_d_i_n_g_s
- represents the query read from the user and the names of the
- free variables as obtained using rreeaadd__tteerrmm//33. If this predicate
- succeeds, it should bind _E_x_p_a_n_d_e_d and _E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s to the query
- and bindings to be executed by the toplevel. This predicate
- is used by the toplevel (pprroolloogg//00). See also eexxppaanndd__aannsswweerr//22 and
- tteerrmm__eexxppaannssiioonn//22.
-
-
- eexxppaanndd__aannsswweerr((_+_B_i_n_d_i_n_g_s_, _-_E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s))
- Hook in module user, normally not defined. Expand the result of
- a successfully executed toplevel query. _B_i_n_d_i_n_g_s is the query
- <_N_a_m_e>= <_V_a_l_u_e>binding list from the query. _E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s must
- be unified with the bindings the toplevel should print.
-
-
- 33..3366 CCrreeaattiinngg aa PPrroottooccooll ooff tthhee UUsseerr IInntteerraaccttiioonn
-
- SWI-Prolog offers the possibility to log the interaction with the user
- on a file. All Prolog interaction, including warnings and tracer
- output, are written on the protocol file.
-
-
- pprroottooccooll((_+_F_i_l_e))
- Start protocolling on file _F_i_l_e. If there is already a protocol
- file open then close it first. If _F_i_l_e exists it is truncated.
-
-
- pprroottooccoollaa((_+_F_i_l_e))
- Equivalent to pprroottooccooll//11, but does not truncate the _F_i_l_e if it
- exists.
-
-
- nnoopprroottooccooll
- Stop making a protocol of the user interaction. Pending output is
- flushed on the file.
-
-
- pprroottooccoolllliinngg((_-_F_i_l_e))
- Succeeds if a protocol was started with pprroottooccooll//11 or pprroottooccoollaa//11
- and unifies _F_i_l_e with the current protocol output file.
-
-
- 33..3377 DDeebbuuggggiinngg aanndd TTrraacciinngg PPrrooggrraammss
-
-
- ttrraaccee
- Start the tracer. ttrraaccee//00 itself cannot be seen in the tracer.
- Note that the Prolog toplevel treats ttrraaccee//00 special; it means
- `trace the next goal'.
-
-
- ttrraacciinngg
- Succeeds when the tracer is currently switched on. ttrraacciinngg//00
- itself can not be seen in the tracer.
-
-
- nnoottrraaccee
- Stop the tracer. nnoottrraaccee//00 itself cannot be seen in the tracer.
-
-
- ttrraaccee((_+_P_r_e_d))
- Equivalent to trace(Pred, +all).
-
-
- ttrraaccee((_+_P_r_e_d_, _+_P_o_r_t_s))
- Put a trace-point on all predicates satisfying the predicate
- specification _P_r_e_d. _P_o_r_t_s is a list of portnames (call, redo,
- exit, fail). The atom all refers to all ports. If the port is
- preceded by a - sign the trace-point is cleared for the port. If
- it is preceded by a + the trace-point is set.
-
- The predicate ttrraaccee//22 activates debug mode (see ddeebbuugg//00). Each
- time a port (of the 4-port model) is passed that has a trace-point
- set the goal is printed as with ttrraaccee//00. Unlike ttrraaccee//00 however,
- the execution is continued without asking for further information.
- Examples:
-
- ?- trace(hello). Trace all ports of hello with any
- arity in any module.
- ?- trace(foo/2, +fail). Trace failures of foo/2 in any
- module.
- ?- trace(bar/1, -all). Stop tracing bar/1.
-
- The predicate ddeebbuuggggiinngg//00 shows all currently defined trace-points.
-
-
- nnoottrraaccee((_+_G_o_a_l))
- Call _G_o_a_l, but suspend the debugger while _G_o_a_l is executing.
- The current implementation cuts the choicepoints of _G_o_a_l after
- successful completion. See oonnccee//11. Later implementations may have
- the same semantics as ccaallll//11.
-
-
- ddeebbuugg
- Start debugger (stop at spy points).
-
-
- nnooddeebbuugg
- Stop debugger (do not trace, nor stop at spy points).
-
-
- ddeebbuuggggiinngg
- Print debug status and spy points on current output stream.
-
-
- ssppyy((_+_P_r_e_d))
- Put a spy point on all predicates meeting the predicate
- specification _P_r_e_d. See section 3.3.
-
-
- nnoossppyy((_+_P_r_e_d))
- Remove spy point from all predicates meeting the predicate
- specification _P_r_e_d.
-
-
- nnoossppyyaallll
- Remove all spy points from the entire program.
-
-
- lleeaasshh((_?_P_o_r_t_s))
- Set/query leashing (ports which allow for user interaction). _P_o_r_t_s
- is one of _+_N_a_m_e, _-_N_a_m_e, _?_N_a_m_e or a list of these. _+_N_a_m_e enables
- leashing on that port, _-_N_a_m_e disables it and _?_N_a_m_e succeeds or
- fails according to the current setting. Recognised ports are:
- call, redo, exit, fail and unify. The special shorthand all refers
- to all ports, full refers to all ports except for the unify port
- (default). half refers to the call, redo and fail port.
-
-
- vviissiibbllee((_+_P_o_r_t_s))
- Set the ports shown by the debugger. See lleeaasshh//11 for a description
- of the port specification. Default is full.
-
-
- uunnkknnoowwnn((_-_O_l_d_, _+_N_e_w))
- Unify _O_l_d with the current value of the unknown system flag.
- On success _N_e_w will be used to specify the new value. _N_e_w
- should be instantiated to either fail or trace and determines
- the interpreters action when an undefined predicate which is not
- declared dynamic is encountered (see ddyynnaammiicc//11). fail implies
- the predicate just fails silently. trace implies the tracer
- is started. Default is trace. The unknown flag is local to
- each module and uunnkknnoowwnn//22 is module transparent. Using it as a
- directive in a module file will only change the unknown flag for
- that module. Using the :/2 construct the behaviour on trapping
- an undefined predicate can be changed for any module. Note that
- if the unknown flag for a module equals fail the system will not
- call eexxcceeppttiioonn//33 and will nnoott try to resolve the predicate via the
- dynamic library system. The system will still try to import the
- predicate from the public module.
-
-
- ssttyyllee__cchheecckk((_+_S_p_e_c))
- Set style checking options. _S_p_e_c is either +<_o_p_t_i_o_n>, -<_o_p_t_i_o_n>,
- ?<_o_p_t_i_o_n> or a list of such options. +<_o_p_t_i_o_n> sets a style
- checking option, -<_o_p_t_i_o_n>clears it and ?<_o_p_t_i_o_n> succeeds or fails
- according to the current setting. ccoonnssuulltt//11 and derivatives resets
- the style checking options to their value before loading the file.
- If---for example---a file containing long atoms should be loaded
- the user can start the file with:
-
- :- style_check(-atom).
-
- Currently available options are:
-
- ____________________________________________________________________
- |_Name__________|Default_|Description_______________________________||singletonon| ||
-
- | rreeaadd__ccllaauussee//11 (used by ccoonnssuulltt//11) warns | ||
- | on variables only appearing once in a | ||
- | term (clause) which have a name not | ||
-
- ||atom | on |starting with an underscore. || ||
-
- | | |rreeaadd//11 and derivatives will produce an |
- | | |error message on quoted atoms or strings |
- | | |longer than 5 lines. |
- | dollar | off |Accept dollar as a lower case character, |
- | | |thus avoiding the need for quoting atoms |
- | | |with dollar signs. System maintenance |
- | | |use only. |
- | discontiguous | on |Warn if the clauses for a predicate are |
-
- | | |not together in the same source file. |
- | string | off |Read and derivatives transform "..." |
- | | |into a prolog string instead of a list |
- |_______________|________|of_ASCII_characters.______________________|
-
-
- 33..3388 OObbttaaiinniinngg RRuunnttiimmee SSttaattiissttiiccss
-
-
- ssttaattiissttiiccss((_+_K_e_y_, _-_V_a_l_u_e))
- Unify system statistics determined by _K_e_y with _V_a_l_u_e. The possible
- keys are given in the table 3.2.
- _______________________________________________________________
- | cputime |(User) cpu time since Prolog was started in|
- | |seconds |
- | inferences |Total number of passes via the call and redo|
- | |ports since Prolog was started. |
- | heap |Estimated total size of the heap (see|
-
- | |section 2.12.1.1) |
- | heapused |Bytes heap in use by Prolog. |
- | heaplimit |Maximum size of the heap (see sec-|
- | |tion 2.12.1.1) |
- | local |Allocated size of the local stack in bytes. |
- | localused |Number of bytes in use on the local stack. |
- | locallimit |Size to which the local stack is allowed to|
- | |grow |
-
- | global |Allocated size of the global stack in bytes. |
- | globalused |Number of bytes in use on the global stack. |
- | globallimit |Size to which the global stack is allowed to|
- | |grow |
- | trail |Allocated size of the trail stack in bytes. |
- | trailused |Number of bytes in use on the trail stack. |
- | traillimit |Size to which the trail stack is allowed to|
-
- | |grow |
- | atoms |Total number of defined atoms. |
- | functors |Total number of defined name/arity pairs. |
- | predicates |Total number of predicate definitions. |
- | modules |Total number of module definitions. |
- |_codes_______|Total_amount_of_byte_codes_in_all_clauses._____|_
-
- Table 3.2: Keys for ssttaattiissttiiccss//22
-
-
- ssttaattiissttiiccss
- Display a table of system statistics on the current output stream.
-
-
- ttiimmee((_+_G_o_a_l))
- Execute _G_o_a_l just like oonnccee//11 (i.e. leaving no choice points),
- but print used time, number of logical inferences and the average
- number of _l_i_p_s (logical inferences per second). Note that
- SWI-Prolog counts the actual executed number of inferences rather
- than the number of passes through the call- and redo ports of the
- theoretical 4-port model.
-
-
- 33..3399 FFiinnddiinngg PPeerrffoorrmmaannccee BBoottttlleenneecckkss
-
- SWI-Prolog offers a statistical program profiler similar to Unix
- prof(1) for C and some other languages. A profiler is used as an aid
- to find performance pigs in programs. It provides information on the
- time spent in the various Prolog predicates.
-
- The profiler is based on the assumption that if we monitor the
- functions on the execution stack on time intervals not correlated to
- the program's execution the number of times we find a procedure on the
- environment stack is a measure of the time spent in this procedure.
- It is implemented by calling a procedure each time slice Prolog is
- active. This procedure scans the local stack and either just counts
- the procedure on top of this stack (plain profiling) or all procedures
- on the stack (cumulative profiling). To get accurate results each
- procedure one is interested in should have a reasonable number of
- counts. Typically a minute runtime will suffice to get a rough
- overview of the most expensive procedures.
-
-
- pprrooffiillee((_+_G_o_a_l_, _+_S_t_y_l_e_, _+_N_u_m_b_e_r))
- Execute _G_o_a_l just like ttiimmee//11. Collect profiling statistics
- according to style (see pprrooffiilleerr//22) and show the top _N_u_m_b_e_r
- procedures on the current output stream (see sshhooww__pprrooffiillee//11).
- The results are kept in the database until rreesseett__pprrooffiilleerr//00 or
- pprrooffiillee//33 is called and can be displayed again with sshhooww__pprrooffiillee//11.
- pprrooffiillee//33 is the normal way to invoke the profiler. The predicates
- below are low-level predicates that can be used for special cases.
-
-
- sshhooww__pprrooffiillee((_+_N_u_m_b_e_r))
- Show the collected results of the profiler. Stops the profiler
- first to avoid interference from sshhooww__pprrooffiillee//11. It shows the top
- _N_u_m_b_e_r predicates according the percentage cpu-time used.
-
-
- pprrooffiilleerr((_-_O_l_d_, _+_N_e_w))
- Query or change the status of the profiler. The status is one
- of off, plain or cumulative. plain implies the time used by
- children of a predicate is not added to the time of the predicate.
- For status cumulative the time of children is added (except for
- recursive calls). Cumulative profiling implies the stack is
- scanned up to the top on each time slice to find all active
- predicates. This implies the overhead grows with the number of
- active frames on the stack. Cumulative profiling starts debugging
- mode to disable tail recursion optimisation, which would otherwise
- remove the necessary parent environments. Switching status from
- plain to cumulative resets the profiler. Switching to and from
- status off does not reset the collected statistics, thus allowing
- to suspend profiling for certain parts of the program.
-
-
- rreesseett__pprrooffiilleerr
- Switches the profiler to off and clears all collected statistics.
-
-
- pprrooffiillee__ccoouunntt((_+_H_e_a_d_, _-_C_a_l_l_s_, _-_P_r_o_m_i_l_a_g_e))
- Obtain profile statistics of the predicate specified by _H_e_a_d. _H_e_a_d
- is an atom for predicates with arity 0 or a term with the same
- name and arity as the predicate required (see ccuurrrreenntt__pprreeddiiccaattee//22).
- _C_a_l_l_s is unified with the number of `calls' and `redos' while the
- profiler was active. _P_r_o_m_i_l_a_g_e is unified with the relative number
- of counts the predicate was active (cumulative) or on top of the
- stack (plain). _P_r_o_m_i_l_a_g_e is an integer between 0 and 1000.
-
-
- 33..4400 MMeemmoorryy MMaannaaggeemmeenntt
-
- Note: lliimmiitt__ssttaacckk//22and ttrriimm__ssttaacckkss//00have no effect on machines that
- do not offer dynamic stack expansion. On these machines these
- predicates simply succeed to improve portability.
-
-
- ggaarrbbaaggee__ccoolllleecctt
- Invoke the global- and trail stack garbage collector. Normally
- the garbage collector is invoked automatically if necessary.
- Explicit invocation might be useful to reduce the need for
- garbage collections in time critical segments of the code. After
- the garbage collection ttrriimm__ssttaacckkss//00 is invoked to release the
- collected memory resources.
-
-
- lliimmiitt__ssttaacckk((_+_K_e_y_, _+_K_b_y_t_e_s))
- Limit one of the stack areas to the specified value. _K_e_y is one of
- local, global or trail. The limit is an integer, expressing the
- desired stack limit in K bytes. If the desired limit is smaller
- than the currently used value, the limit is set to the nearest
- legal value above the currently used value. If the desired value
- is larger than the maximum, the maximum is taken. Finally, if the
- desired value is either 0 or the atom unlimited the limit is set to
- its maximum. The maximum and initial limit is determined by the
- command line options -L, -G and -T.
-
-
- ttrriimm__ssttaacckkss
- Release stack memory resources that are not in use at this moment,
- returning them to the operating system. Trim stack is a relatively
- cheap call. It can be used to release memory resources in a
- backtracking loop, where the iterations require typically seconds
- of execution time and very different, potentially large, amounts of
- stack space. Such a loop should be written as follows:
-
- loop :-
- generator,
- trim_stacks,
- potentially_expensive_operation,
- stop_condition, !.
-
- The prolog top level loop is written this way, reclaiming memory
- resources after every user query.
-
-
- ssttaacckk__ppaarraammeetteerr((_+_S_t_a_c_k_, _+_K_e_y_, _-_O_l_d_, _+_N_e_w))
- Query/set a parameter for the runtime stacks. _S_t_a_c_k is one of
- local, global, trail or argument. The table below describes the
- _K_e_y/_V_a_l_u_e pairs. Old is first unified with the current value.
-
- ____________________________________________________________
- | limit |Maximum size of the stack in bytes |
- |_min_free_|Minimum_free_space_at_entry_of_foreign_predicate_|
-
- This predicate is currently only available on versions that use the
- stack-shifter to enlarge the runtime stacks when necessary. It's
- definition is subject to change.
-
-
- 33..4411 WWiinnddoowwss DDDDEE iinntteerrffaaccee
-
- The predicates in this section deal with MS-Windows `Dynamic Data
- Exchange' or DDE protocol. A Windows DDE conversation is a form
- of interprocess communication based on sending reserved window-events
- between the communicating processes.
-
- See also section 5.4 for loading Windows DLL's into SWI-Prolog.
-
-
- 33..4411..11 DDDDEE cclliieenntt iinntteerrffaaccee
-
- The DDE client interface allows Prolog to talk to DDE server programs.
- We will demonstrate the use of the DDE interface using the Windows
- PROGMAN (Program Manager) application:
-
- 1 ?- open_dde_conversation(progman, progman, C).
-
- C = 0
- 2 ?- dde_request(0, groups, X)
-
- --> Unifies X with description of groups
-
- 3 ?- dde_execute(0, '[CreateGroup("DDE Demo")]').
-
- Yes
-
- 4 ?- close_dde_conversation(0).
-
- Yes
-
- For details on interacting with progman, use the SDK online
- manual section on the Shell DDE interface. See also the Prolog
- library(progman), which may be used to write simple Windows setup
- scripts in Prolog.
-
-
- ooppeenn__ddddee__ccoonnvveerrssaattiioonn((_+_S_e_r_v_i_c_e_, _+_T_o_p_i_c_, _-_H_a_n_d_l_e))
- Open a conversation with a server supporting the given service name
- and topic (atoms). If successful, _H_a_n_d_l_e may be used to send
- transactions to the server. If no willing server is found this
- predicate fails silently.
-
-
- cclloossee__ddddee__ccoonnvveerrssaattiioonn((_+_H_a_n_d_l_e))
- Close the conversation associated with _H_a_n_d_l_e. All opened
- conversations should be closed when they're no longer needed,
- although the system will close any that remain open on process
- termination.
-
-
- ddddee__rreeqquueesstt((_+_H_a_n_d_l_e_, _+_I_t_e_m_, _-_V_a_l_u_e))
- Request a value from the server. _I_t_e_m is an atom that identifies
- the requested data, and _V_a_l_u_e will be a string (CF_TEXT data
- in DDE parlance) representing that data, if the request is
- successful. If unsuccessful, _V_a_l_u_e will be unified with a term
- of form error(<_R_e_a_s_o_n>), identifying the problem. This call uses
- SWI-Prolog string objects to return the value rather then atoms
- to reduce the load on the atom-space. See section 3.20 for a
- discussion on this data type.
-
-
- ddddee__eexxeeccuuttee((_+_H_a_n_d_l_e_, _+_C_o_m_m_a_n_d))
- Request the DDE server to execute the given command-string.
- Succeeds if the command could be executed and fails with error
- message otherwise.
-
-
- ddddee__ppookkee((_+_H_a_n_d_l_e_, _+_I_t_e_m_, _+_C_o_m_m_a_n_d))
- Issue a POKE command to the server on the specified _I_t_e_m. Command
- is passed as data of type CF_TEXT.
-
-
- 33..4411..22 DDDDEE sseerrvveerr mmooddee
-
- The (autoload) library(dde) defines primitives to realise simple DDE
- server applications in SWI-Prolog. These features are provided as of
- version 2.0.6 and should be regarded prototypes. The C-part of the DDE
- server can handle some more primitives, so if you need features not
- provided by this interface, please study library(dde).
-
-
- ddddee__rreeggiisstteerr__sseerrvviiccee((_+_T_e_m_p_l_a_t_e_, _+_G_o_a_l))
- Register a server to handle DDE request or DDE execute requests
- from other applications. To register a service for a DDE request,
- _T_e_m_p_l_a_t_e is of the form:
-
- +Service(+Topic, +Item, +Value)
-
- _S_e_r_v_i_c_e is the name of the DDE service provided (like progman in
- the client example above). _T_o_p_i_c is either an atom, indicating
- _G_o_a_l only handles requests on this topic or a variable that also
- appears in _G_o_a_l. _I_t_e_m and _V_a_l_u_e are variables that also appear in
- _G_o_a_l.
-
- The example below registers the Prolog ffeeaattuurree//22 predicate to be
- accessible from other applications. The request may be given from
- the same Prolog as well as from another application.
-
- ?- dde_register_service(prolog(feature, F, V),
- feature(F, V)).
-
- ?- open_dde_conversation(prolog, feature, Handle),
- dde_request(Handle, home, Home),
- close_dde_conversation(Handle).
-
- Home = '/usr/local/lib/pl-2.0.6/'
-
- Handling DDE execute requests is very similar. In this case the
- template is of the form:
-
- +Service(+Topic, +Item)
-
- Passing a _V_a_l_u_e argument is not needed as execute requests either
- succeed or fail. If _G_o_a_l fails, a `not processed' is passed back
- to the caller of the DDE request.
-
-
- ddddee__uunnrreeggiisstteerr__sseerrvviiccee((_+_S_e_r_v_i_c_e))
- Stop responding to _S_e_r_v_i_c_e. If Prolog is halted, it will
- automatically call this on all open services.
-
-
- ddddee__ccuurrrreenntt__sseerrvviiccee((_-_S_e_r_v_i_c_e_, _-_T_o_p_i_c))
- Find currently registered services and the topics served on them.
-
-
- ddddee__ccuurrrreenntt__ccoonnnneeccttiioonn((_-_S_e_r_v_i_c_e_, _-_T_o_p_i_c))
- Find currently open conversations.
-
-
- 33..4422 MMiisscceellllaanneeoouuss
-
-
- ddwwiimm__mmaattcchh((_+_A_t_o_m_1_, _+_A_t_o_m_2))
- Succeeds if _A_t_o_m_1 matches _A_t_o_m_2 in `Do What I Mean' sense. Both
- _A_t_o_m_1 and _A_t_o_m_2 may also be integers or floats. The two atoms
- match if:
-
- o They are identical
-
- o They differ by one character (spy spu)
-
- o One character is inserted/deleted (debug deug)
-
- o Two characters are transposed (trace tarce)
-
- o `Sub-words' are glued differently (existsfile existsFile
- exists_file)
-
- o Two adjacent sub words are transposed (existsFile
- fileExists)
-
-
- ddwwiimm__mmaattcchh((_+_A_t_o_m_1_, _+_A_t_o_m_2_, _-_D_i_f_f_e_r_e_n_c_e))
- Equivalent to ddwwiimm__mmaattcchh//22, but unifies _D_i_f_f_e_r_e_n_c_e with an atom
- identifying the the difference between _A_t_o_m_1 and _A_t_o_m_2. The return
- values are (in the same order as above): equal, mismatched_char,
- inserted_char, transposed_char, separated and transposed_word.
-
-
- wwiillddccaarrdd__mmaattcchh((_+_P_a_t_t_e_r_n_, _+_S_t_r_i_n_g))
- Succeeds if _S_t_r_i_n_g matches the wildcard pattern _P_a_t_t_e_r_n. _P_a_t_t_e_r_n
- is very similar the the Unix csh pattern matcher. The patterns are
- given below:
-
- ? Matches one arbitrary character.
-
- * Matches any number of arbitrary characters.
- [...] Matches one of the characters specified between the brackets. <_c_h_a_r_1>-<_c_h_a_r_2>indicates a range.
- {...} Matches any of the patterns of the comma separated list between the braces.
-
- Example:
-
- ?- wildcard_match('[a-z]*.{pro,pl}[%~]', 'a_hello.pl%').
-
- Yes.
-
-
- ggeennssyymm((_+_B_a_s_e_, _-_U_n_i_q_u_e))
- Generate a unique atom from base _B_a_s_e and unify it with _U_n_i_q_u_e.
- _B_a_s_e should be an atom. The first call will return <_b_a_s_e>1, the
- next <_b_a_s_e>2, etc. Note that this is no warrant that the atom is
- unique in the system.
-
-
- sslleeeepp((_+_T_i_m_e))
- Suspend execution _T_i_m_e seconds. _T_i_m_e is either a floating point
- number or an integer. Granularity is dependent on the system's
- timer granularity. A negative time causes the timer to return
- immediately. On most non-realtime operating systems we can only
- ensure execution is suspended for aatt lleeaasstt _T_i_m_e seconds.
-
-
- CChhaapptteerr 44.. UUSSIINNGG MMOODDUULLEESS
-
-
- 44..11 WWhhyy UUssiinngg MMoodduulleess??
-
- In traditional Prolog systems the predicate space was flat. This
- approach is not very suitable for the development of large
- applications, certainly not if these applications are developed by more
- than one programmer. In many cases, the definition of a Prolog
- predicate requires sub-predicates that are intended only to complete
- the definition of the main predicate. With a flat and global predicate
- space these support predicates will be visible from the entire program.
-
- For this reason, it is desirable that each source module has it's own
- predicate space. A module consists of a declaration for it's name,
- it's _p_u_b_l_i_c _p_r_e_d_i_c_a_t_e_s and the predicates themselves. This approach
- allow the programmer to use short (local) names for support predicates
- without worrying about name conflicts with the support predicates of
- other modules. The module declaration also makes explicit which
- predicates are meant for public usage and which for private purposes.
- Finally, using the module information, cross reference programs can
- indicate possible problems much better.
-
-
- 44..22 NNaammee--bbaasseedd vveerrssuuss PPrreeddiiccaattee--bbaasseedd MMoodduulleess
-
- Two approaches to realize a module system are commonly used in Prolog
- and other languages. The first one is the _n_a_m_e _b_a_s_e_d module system.
- In these systems, each atom read is tagged (normally prefixed) with
- the module name, with the exception of those atoms that are defined
- _p_u_b_l_i_c. In the second approach, each module actually implements its
- own predicate space.
-
- A critical problem with using modules in Prolog is introduced by
- the meta-predicates that transform between Prolog data and Prolog
- predicates. Consider the case where we write:
-
- :- module(extend, [add_extension/3]).
-
- add_extension(Extension, Plain, Extended) :-
- maplist(extend_atom(Extension), Plain, Extended).
-
- extend_atom(Extension, Plain, Extended) :-
- concat(Plain, Extension, Extended).
-
- In this case we would like maplist to call extend_atom/3 in the module
- extend. A name based module system will do this correctly. It will
- tag the atom extend_atom with the module and maplist will use this to
- construct the tagged term extend_atom/3. A name based module however,
- will not only tag the atoms that will eventually be used to refer to a
- predicate, but aallll atoms that are not declared public. So, with a name
- based module system also data is local to the module. This introduces
- another serious problem:
-
- :- module(action, [action/3]).
-
- action(Object, sleep, Arg) :- ....
- action(Object, awake, Arg) :- ....
-
- :- module(process, [awake_process/2]).
-
- awake_process(Process, Arg) :-
- action(Process, awake, Arg).
-
- This code uses a simple object-oriented implementation technique were
- atoms are used as method selectors. Using a name based module system,
- this code will not work, unless we declare the selectors public atoms
- in all modules that use them. Predicate based module systems do not
- require particular precautions for handling this case.
-
- It appears we have to choose either to have local data, or to
- have trouble with meta-predicates. Probably it is best to choose
- for the predicate based approach as novice users will not often
- write generic meta-predicates that have to be used across multiple
- modules, but are likely to write programs that pass data around across
- modules. Experienced Prolog programmers should be able to deal with
- the complexities of meta-predicates in a predicate based module system.
-
-
- 44..33 DDeeffiinniinngg aa MMoodduullee
-
- Modules normally are created by loading a _m_o_d_u_l_e _f_i_l_e. A module file
- is a file holding a mmoodduullee//22 directive as its first term. The mmoodduullee//22
- directive declares the name and the public (i.e. externally visible)
- predicates of the module. The rest of the file is loaded into the
- module. Below is an example of a module file, defining rreevveerrssee//22.
-
- :- module(reverse, [reverse/2]).
-
- reverse(List1, List2) :-
- rev(List1, [], List2).
-
- rev([], List, List).
- rev([Head|List1], List2, List3) :-
- rev(List1, [Head|List2], List3).
-
-
- 44..44 IImmppoorrttiinngg PPrreeddiiccaatteess iinnttoo aa MMoodduullee
-
- As explained before, in the predicate based approach adapted by
- SWI-Prolog, each module has it's own predicate space. In SWI-Prolog,
- a module initially is completely empty. Predicates can be added to
- a module by loading a module file as demonstrated in the previous
- section, using assert or by _i_m_p_o_r_t_i_n_g them from another module.
-
- Two mechanisms for importing predicates explicitly from another module
- exist. The uussee__mmoodduullee//[[11,,22]] predicates load a module file and import
- (part of the) public predicates of the file. The iimmppoorrtt//11 predicate
- imports any predicate from any module.
-
-
- uussee__mmoodduullee((_+_F_i_l_e))
- Load the file(s) specified with _F_i_l_e just like eennssuurree__llooaaddeedd//11.
- The files should all be module files. All exported predicates
- from the loaded files are imported into the context module.
- The difference between this predicate and eennssuurree__llooaaddeedd//11 becomes
- apparent if the file is already loaded into another module. In
- this case eennssuurree__llooaaddeedd//11 does nothing; use_module will import all
- public predicates of the module into the current context module.
-
-
- uussee__mmoodduullee((_+_F_i_l_e_, _+_I_m_p_o_r_t_L_i_s_t))
- Load the file specified with _F_i_l_e (only one file is accepted).
- _F_i_l_e should be a module file. _I_m_p_o_r_t_L_i_s_t is a list of name/arity
- pairs specifying the predicates that should be imported from the
- loaded module. If a predicate is specified that is not exported
- from the loaded module a warning will be printed. The predicate
- will nevertheless be imported to simplify debugging.
-
-
- iimmppoorrtt((_+_H_e_a_d))
- Import predicate _H_e_a_d into the current context module. _H_e_a_d should
- specify the source module using the <_m_o_d_u_l_e>:<_t_e_r_m>construct. Note
- that predicates are normally imported using one of the directives
- uussee__mmoodduullee//[[11,,22]]. iimmppoorrtt//11 is meant for handling imports into
- dynamically created modules.
-
- It would be rather inconvenient to have to import each predicate
- referred to by the module, including the system predicates. For this
- reason each module is assigned a _d_e_f_a_u_l_t _m_o_d_u_l_e. All predicates in
- the default module are available without extra declarations. Their
- definition however can be overruled in the local module. This schedule
- is implemented by the exception handling mechanism of SWI-Prolog: if
- an undefined predicate exception is raised for a predicate in some
- module, the exception handler first tries to import the predicate from
- the module's default module. On success, normal execution is resumed.
-
-
- 44..44..11 RReesseerrvveedd MMoodduulleess
-
- SWI-Prolog contains two special modules. The first one is the module
- system. This module contains all built-in predicates described in
- this manual. Module system has no default module assigned to it.
- The second special module is the module user. This module forms the
- initial working space of the user. Initially it is empty. The
- default module of module user is system, making all built-in predicate
- definitions available as defaults. Built-in predicates thus can be
- overruled by defining them in module user before they are used.
-
- All other modules default to module user. This implies they can use
- all predicates imported into user without explicitly importing them.
-
-
- 44..55 UUssiinngg tthhee MMoodduullee SSyysstteemm
-
- The current structure of the module system has been designed with
- some specific organisations for large programs in mind. Many large
- programs define a basic library layer on top of which the actual
- program itself is defined. The module user, acting as the default
- module for all other modules of the program can be used to distribute
- these definitions over all program module without introducing the need
- to import this common layer each time explicitly. It can also be
- used to redefine built-in predicates if this is required to maintain
- compatibility to some other Prolog implementation. Typically, the
- loadfile of a large application looks like this:
-
- :- use_module(compatibility). % load XYZ prolog compatibility
-
- :- use_module( % load generic parts
- [ error % errors and warnings
- , goodies % general goodies (library extensions)
- , debug % application specific debugging
- , virtual_machine % virtual machine of application
- , ... % more generic stuff
- ]).
-
- :- ensure_loaded(
- [ ... % the application itself
- ]).
-
- The `use_module' declarations will import the public predicates from
- the generic modules into the user module. The `ensure_loaded'
- directive loads the modules that constitute the actual application.
- It is assumed these modules import predicates from each other using
- uussee__mmoodduullee//[[11,,22]]as far as necessary.
-
- In combination with the object-oriented schema described below it is
- possible to define a neat modular architecture. The generic code
- defines general utilities and the message passing predicates (invoke/3
- in the example below). The application modules define classes that
- communicate using the message passing predicates.
-
-
- 44..55..11 OObbjjeecctt OOrriieenntteedd PPrrooggrraammmmiinngg
-
- Another typical way to use the module system is for defining classes
- within an object oriented paradigm. The class structure and the
- methods of a class can be defined in a module and the explicit
- module-boundary overruling describes in section 4.6.2 can by used by
- the message passing code to invoke the behaviour. An outline of this
- mechanism is given below.
-
- % Define class point
-
- :- module(point, []). % class point, no exports
-
- % name type, default access
- % value
-
- variable(x, integer, 0, both).
- variable(y, integer, 0, both).
-
- % method name predicate name arguments
-
- behaviour(mirror, mirror, []).
-
- mirror(P) :-
- fetch(P, x, X),
- fetch(P, y, Y),
- store(P, y, X),
- store(P, x, Y).
-
- The predicates fetch/3 and store/3 are predicates that change instance
- variables of instances. The figure below indicates how message passing
- can easily be implemented:
-
- % invoke(+Instance, +Selector, ?ArgumentList)
- % send a message to an instance
-
- invoke(I, S, Args) :-
- class_of_instance(I, Class),
- Class:behaviour(S, P, ArgCheck), !,
- convert_arguments(ArgCheck, Args, ConvArgs),
- Goal =.. [P|ConvArgs],
- Class:Goal.
-
- The construct <_M_o_d_u_l_e>:<_G_o_a_l> explicitly calls _G_o_a_l in module _M_o_d_u_l_e.
- It is discussed in more detail in section 3.7.
-
-
- 44..66 MMeettaa--PPrreeddiiccaatteess iinn MMoodduulleess
-
- As indicated in the introduction, the problem with a predicate based
- module system lies in the difficulty to find the correct predicate from
- a Prolog term. The predicate `solution(Solution)' can exist in more
- than one module, but `assert(solution(4))' in some module is supposed
- to refer to the correct version of solution/1.
-
- Various approaches are possible to solve this problem. One is to
- add an extra argument to all predicates (e.g. `assert(Module, Term)').
- Another is to tag the term somehow to indicate which module is desired
- (e.g. `assert(Module:Term)'). Both approaches are not very attractive
- as they make the user responsible for choosing the correct module,
- inviting unclear programming by asserting in other modules. The
- predicate aasssseerrtt//11 is supposed to assert in the module it is called
- from and should do so without being told explicitly. For this reason,
- the notion _c_o_n_t_e_x_t _m_o_d_u_l_e has been introduced.
-
-
- 44..66..11 DDeeffiinniittiioonn aanndd CCoonntteexxtt MMoodduullee
-
- Each predicate of the program is assigned a module, called it's
- _d_e_f_i_n_i_t_i_o_n _m_o_d_u_l_e. The definition module of a predicate is always the
- module in which the predicate was originally defined. Each active goal
- in the Prolog system has a _c_o_n_t_e_x_t _m_o_d_u_l_e assigned to it.
-
- The context module is used to find predicates from a Prolog term.
- By default, this module is the definition module of the predicate
- running the goal. For meta-predicates however, this is the context
- module of the goal that invoked them. We call this _m_o_d_u_l_e___t_r_a_n_s_p_a_r_e_n_t
- in SWI-Prolog. In the `using maplist' example above, the predicate
- mmaapplliisstt//33 is declared module_transparent. This implies the context
- module remains extend, the context module of add_extension/3. This way
- mmaapplliisstt//33 can decide to call extend_atom in module extend rather than in
- it's own definition module.
-
- All built-in predicates that refer to predicates via a Prolog term are
- declared module_transparent. Below is the code defining maplist.
-
- :- module(maplist, maplist/3).
-
- :- module_transparent maplist/3.
-
- % maplist(+Goal, +List1, ?List2)
- % True if Goal can successfully be applied to all succes-
- sive pairs
- % of elements of List1 and List2.
-
- maplist(_, [], []).
- maplist(Goal, [Elem1|Tail1], [Elem2|Tail2]) :-
- apply(Goal, [Elem1, Elem2]),
- maplist(Goal, Tail1, Tail2).
-
-
- 44..66..22 OOvveerrrruulliinngg MMoodduullee BBoouunnddaarriieess
-
- The mechanism above is sufficient to create an acceptable module
- system. There are however cases in which we would like to be able to
- overrule this schema and explicitly call a predicate in some module
- or assert explicitly in some module. The first is useful to invoke
- goals in some module from the user's toplevel or to implement a
- object-oriented system (see above). The latter is useful to create and
- modify _d_y_n_a_m_i_c _m_o_d_u_l_e_s (see section 4.7).
-
- For this purpose, the reserved term ://22 has been introduced. All
- built-in predicates that transform a term into a predicate reference
- will check whether this term is of the form `<_M_o_d_u_l_e>:<_T_e_r_m>'. If so,
- the predicate is searched for in _M_o_d_u_l_e instead of the goal's context
- module. The : operator may be nested, in which case the inner-most
- module is used.
-
- The special calling construct <_M_o_d_u_l_e>:<_G_o_a_l>pretends _G_o_a_l is called
- from _M_o_d_u_l_e instead of the context module. Examples:
-
- ?- assert(world:done). % asserts done/0 into module world
- ?- world:assert(done). % the same
- ?- world:done. % calls done/0 in module world
-
-
- 44..77 DDyynnaammiicc MMoodduulleess
-
- So far, we discussed modules that were created by loading a
- module-file. These modules have been introduced on facilitate
- the development of large applications. The modules are fully
- defined at load-time of the application and normally will not change
- during execution. Having the notion of a set of predicates as a
- self-contained world can be attractive for other purposes as well. For
- example, assume an application that can reason about multiple worlds.
- It is attractive to store the data of a particular world in a module,
- so we extract information from a world simply by invoking goals in this
- world.
-
- Dynamic modules can easily be created. Any built-in predicate that
- tries to locate a predicate in a specific module will create this
- module as a side-effect if it did not yet exist. Example:
-
- ?- assert(world_a:consistent),
- world_a:unknown(_, fail).
-
- These calls create a module called `world_a' and make the call
- `world_a:consistent' succeed. Undefined predicates will not start the
- tracer or autoloader for this module (see uunnkknnoowwnn//22).
-
- Import and export from dynamically created world is arranged via the
- predicates iimmppoorrtt//11 and eexxppoorrtt//11:
-
- ?- world_b:export(solve(_,_)). % exports solve/2 from world_b
- ?- world_c:import(world_b:solve(_,_)). % and import it to world_c
-
-
- 44..88 MMoodduullee HHaannddlliinngg PPrreeddiiccaatteess
-
- This section gives the predicate definitions for the remaining built-in
- predicates that handle modules.
-
-
- ::-- mmoodduullee((_+_M_o_d_u_l_e_, _+_P_u_b_l_i_c_L_i_s_t))
- This directive can only be used as the first term of a source file.
- It declares the file to be a _m_o_d_u_l_e _f_i_l_e, defining _M_o_d_u_l_e and
- exporting the predicates of _P_u_b_l_i_c_L_i_s_t. _P_u_b_l_i_c_L_i_s_t is a list of
- name/arity pairs.
-
-
- mmoodduullee__ttrraannssppaarreenntt _+_P_r_e_d_s
- _P_r_e_d_s is a comma separated list of name/arity pairs (like
- ddyynnaammiicc//11). Each goal associated with a transparent declared
- predicate will inherit the _c_o_n_t_e_x_t _m_o_d_u_l_e from its parent goal.
-
-
- mmeettaa__pprreeddiiccaattee _+_H_e_a_d_s
- This predicate is defined in library(quintus) and provides a
- partial emulation of the Quintus predicate. See section 4.9.1 for
- details.
-
-
- ccuurrrreenntt__mmoodduullee((_-_M_o_d_u_l_e))
- Generates all currently known modules.
-
-
- ccuurrrreenntt__mmoodduullee((_?_M_o_d_u_l_e_, _?_F_i_l_e))
- Is true if _F_i_l_e is the file from which _M_o_d_u_l_e was loaded. _F_i_l_e is
- the internal canonical filename. See also ssoouurrccee__ffiillee//[[11,,22]].
-
-
- ccoonntteexxtt__mmoodduullee((_-_M_o_d_u_l_e))
- Unify _M_o_d_u_l_e with the context module of the current goal.
- ccoonntteexxtt__mmoodduullee//11 itself is transparent.
-
-
- eexxppoorrtt((_+_H_e_a_d))
- Add a predicate to the public list of the context module. This
- implies the predicate will be imported into another module if this
- module is imported with uussee__mmoodduullee//[[11,,22]]. Note that predicates are
- normally exported using the directive mmoodduullee//22. eexxppoorrtt//11 is meant
- to handle export from dynamically created modules.
-
-
- eexxppoorrtt__lliisstt((_+_M_o_d_u_l_e_, _?_E_x_p_o_r_t_s))
- Unifies _E_x_p_o_r_t_s with a list of terms. Each term has the name and
- arity of a public predicate of _M_o_d_u_l_e. The order of the terms in
- _E_x_p_o_r_t_s is not defined. See also pprreeddiiccaattee__pprrooppeerrttyy//22.
-
-
- ddeeffaauulltt__mmoodduullee((_+_M_o_d_u_l_e_, _-_D_e_f_a_u_l_t))
- Succesively unifies _D_e_f_a_u_l_t with the module names from which a call
- in _M_o_d_u_l_e attempts to use the definition. For the module user,
- this will generate user and system. For any other module, this
- will generate the module itself, followed by user and system.
-
-
- mmoodduullee((_+_M_o_d_u_l_e))
- The call module(Module) may be used to switch the default working
- module for the interactive toplevel (see pprroolloogg//00). This may be
- used to when debugging a module. The example below lists the
- clauses of file_of_label/2 in the module tex.
-
- 1 ?- module(tex).
-
- Yes
- tex: 2 ?- listing(file_of_label/2).
- ...
-
-
- 44..99 CCoommppaattiibbiilliittyy ooff tthhee MMoodduullee SSyysstteemm
-
- The principles behind the module system of SWI-Prolog differ in a
- number of aspects from the Quintus Prolog module system.
-
- o The SWI-Prolog module system allows the user to redefine system
- predicates.
-
- o All predicates that are available in the system and user modules
- are visible in all other modules as well.
-
- o Quintus has the `mmeettaa__pprreeddiiccaattee//11' declaration were SWI-Prolog has
- the mmoodduullee__ttrraannssppaarreenntt//11 declaration.
-
- The mmeettaa__pprreeddiiccaattee//11 declaration causes the compiler to tag arguments
- that pass module sensitive information with the module using the ://22
- operator. This approach has some disadvantages:
-
- o Changing a meta_predicate declaration implies all predicates
- ccaalllliinngg the predicate need to be reloaded. This can cause serious
- consistency problems.
-
- o It does not help for dynamically defined predicates calling module
- sensitive predicates.
-
- o It slows down the compiler (at least in the SWI-Prolog
- architecture).
-
- o At least within the SWI-Prolog architecture the run-time overhead
- is larger than the overhead introduced by the transparent
- mechanism.
-
- Unfortunately the transparent predicate approach also has some
- disadvantages. If a predicate A passes module sensitive information
- to a predicate B, passing the same information to a module sensitive
- system predicate both A and B should be declared transparent. Using
- the Quintus approach only A needs to be treated special (i.e. declared
- with mmeettaa__pprreeddiiccaattee//11). A second problem arises if the body of a
- transparent predicate uses module sensitive predicates for which it
- wants to refer to its own module. Suppose we want to define ffiinnddaallll//33
- using aasssseerrtt//11 and rreettrraacctt//11. The example in figure 4.1 gives the
- solution.
- :- module(findall, [findall/3]).
-
- :- dynamic
-
- solution/1.
-
- :- module_transparent
- findall/3,
- store/2.
-
- findall(Var, Goal, Bag) :-
-
- assert(findall:solution('$mark')),
- store(Var, Goal),
- collect(Bag).
-
- store(Var, Goal) :-
- Goal, % refers to context module of
- % caller of findall/3
- assert(findall:solution(Var)),
-
- fail.
- store(_, _).
-
- collect(Bag) :-
- ...,
-
- Figure 4.1: ffiinnddaallll//33 using modules
-
-
- 44..99..11 EEmmuullaattiinngg mmeettaa__pprreeddiiccaattee//11
-
- The Quintus mmeettaa__pprreeddiiccaattee//11 directive can in many cases be replaced
- by the transparent declaration. Below is the definition of
- mmeettaa__pprreeddiiccaattee//11as available from library(quintus).
-
- :- op(1150, fx, (meta_predicate)).
-
- meta_predicate((Head, More)) :- !,
- meta_predicate1(Head),
- meta_predicate(More).
- meta_predicate(Head) :-
- meta_predicate1(Head).
-
- meta_predicate1(Head) :-
- Head =.. [Name|Arguments],
- member(Arg, Arguments),
- module_expansion_argument(Arg), !,
- functor(Head, Name, Arity),
- module_transparent(Name/Arity).
- meta_predicate1(_). % just a mode declaration
-
- module_expansion_argument(:).
- module_expansion_argument(N) :- integer(N).
-
- The discussion above about the problems with the transparent mechanism
- show the two cases in which this simple transformation does not work.
-
-
- CChhaapptteerr 55.. FFOORREEIIGGNN LLAANNGGUUAAGGEE IINNTTEERRFFAACCEE
-
- SWI-Prolog offers a powerful interface to C
- [Kernighan & Ritchie, 1978]. The main design objectives of the
- foreign language interface are flexibility and performance. A foreign
- predicate is a C-function that has the same number of arguments as
- the predicate represented. C-functions are provided to analyse the
- passed terms, convert them to basic C-types as well as to instantiate
- arguments using unification. Non-deterministic foreign predicates are
- supported, providing the foreign function with a handle to control
- backtracking.
-
- C can call Prolog predicates, providing both an query interface and
- an interface to extract multiple solutions from an non-deterministic
- Prolog predicate. There is no limit to the nesting of Prolog calling
- C, calling Prolog, etc. It is also possible to write the `main' in C
- and use Prolog as an embedded logical engine.
-
-
- 55..11 OOvveerrvviieeww ooff tthhee IInntteerrffaaccee
-
- A special include file called SWI-Prolog.h should be included with each
- C-source file that is to be loaded via the foreign interface. The
- installation process installs this file in the directory include in
- the SWI-Prolog home directory (?- feature(home, Home).). This C-header
- file defines various data types, macros and functions that can be used
- to communicate with SWI-Prolog. Functions and macros can be divided
- into the following categories:
-
- o Analysing Prolog terms
-
- o Constructing new terms
-
- o Unifying terms
-
- o Returning control information to Prolog
-
- o Registering foreign predicates with Prolog
-
- o Calling Prolog from C
-
- o Global actions on Prolog (halt, break, abort, etc.)
-
-
- 55..22 LLiinnkkiinngg FFoorreeiiggnn MMoodduulleess
-
- Foreign modules may be linked to Prolog in three ways. Using _s_t_a_t_i_c
- _l_i_n_k_i_n_g, the extensions, a small description file and the basic
- SWI-Prolog object file are linked together to form a new executable.
- Using _d_y_n_a_m_i_c _l_i_n_k_i_n_g, the extensions are linked to a shared library
- (.so file on most Unix systems) or dynamic-link library (.DLL file on
- Microsoft platforms) and loaded into the the running Prolog process..
-
-
- 55..22..11 WWhhaatt lliinnkkiinngg iiss pprroovviiddeedd??
-
- The _s_t_a_t_i_c _l_i_n_k_i_n_g schema can be used on all versions of SWI-Prolog.
- The ffeeaattuurree//22 predicate may be used to find out what other linking
- methods are provided for this version.
-
- o _f_e_a_t_u_r_e_(_o_p_e_n___s_h_a_r_e_d___o_b_j_e_c_t_, _t_r_u_e_)
- If this succeeds the system provides the ooppeenn__sshhaarreedd__oobbjjeecctt//22and
- related predicates that allow for handling Unix shared object files
- based on the Unix library functions ddllooppeenn((2)) and friends. See
- section 5.4.
-
- o _f_e_a_t_u_r_e_(_d_l_l_, _t_r_u_e_)
- If this succeeds the system provides an interface for loading .DLL
- files by means of ooppeenn__ddllll//22 and friends. See section 5.4.
-
- If either the feature open_shared_object or dll is true, the library
- library(shlib) provides a common interface for loading foreign files
- from Prolog.
-
-
- 55..22..22 WWhhaatt kkiinndd ooff llooaaddiinngg sshhoouulldd II bbee uussiinngg??
-
- All described approaches have their advantages and disadvantages.
- Static linking is portable and allows for debugging on all platforms.
- It is relatively cumbersome and the libraries you need to pass to the
- linker may vary from system to system.
-
- Loading shared objects or DLL files provides sharing and protection
- and is generally the best choice. The old (and also badly portable)
- ssaavvee//[[11,,22]] and ssaavvee__pprrooggrraamm//[[11,,22]] do not cooperate with this mechanism,
- but the more recent qqssaavvee__pprrooggrraamm//[[11,,22]]can be used to created programs
- that load the appropriate library at startup.
-
- Note that the definition of the foreign predicates is the same,
- regardless of the linking type used.
-
-
- 55..33 DDyynnaammiicc LLiinnkkiinngg ooff sshhaarreedd lliibbrraarriieess
-
- The interface defined in this section allows the user to load shared
- libraries (.so files on most Unix systems). This interface is portable
- to all machines providing the function ddllooppeenn((2)) or an equivalent,
- normally from the library -ldl. These functions provide the basic
- interface layer. It is advised to use the predicates from section 5.4
- in your application.
-
-
- ooppeenn__sshhaarreedd__oobbjjeecctt((_+_F_i_l_e_, _-_H_a_n_d_l_e))
- _F_i_l_e is the name of a .so file (see your C programmers documenta-
- tion on how to create a .so file). This file is attached to the
- current process and _H_a_n_d_l_e is unified with a handle to the shared
- object. Equivalent to open_shared_object(File, [global], Handle).
- See also llooaadd__ffoorreeiiggnn__lliibbrraarryy//[[11,,22]].
-
-
- ooppeenn__sshhaarreedd__oobbjjeecctt((_+_F_i_l_e_, _+_O_p_t_i_o_n_s_, _-_H_a_n_d_l_e))
- As ooppeenn__sshhaarreedd__oobbjjeecctt//22, but allows for additional flags to be
- passed. _O_p_t_i_o_n_s is a list of atoms. now implies the symbols are
- resolved immediately rather than lazy (default). global implies
- symbols of the loaded object are visible while loading other shared
- objects (by default they are local). Note that these flags may not
- be supported by your operating system. Check the documentation of
- dlopen() or equivalent on your operating system.
-
-
- cclloossee__sshhaarreedd__oobbjjeecctt((_+_H_a_n_d_l_e))
- Detach the shared object identified by _H_a_n_d_l_e.
-
-
- ccaallll__sshhaarreedd__oobbjjeecctt__ffuunnccttiioonn((_+_H_a_n_d_l_e_, _+_F_u_n_c_t_i_o_n))
- Call the named function in the loaded shared library. The function
- is called without arguments and the return-value is ignored.
- Normally this function installs foreign language predicates using
- calls to PPLL__rreeggiisstteerr__ffoorreeiiggnn(()).
-
-
- 55..44 UUssiinngg tthhee lliibbrraarryy sshhlliibb ffoorr .DLL aanndd .so ffiilleess
-
- This section discusses the functionality of the (autoload) library
- shlib.pl, providing an interface to shared libraries. Currently it
- supports MS-Windows DLL (.DLL) libraries and Unix .so (shared object)
- files.
-
-
- llooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b))
- Equivalent to load_foreign_library(Lib, install).
-
-
- llooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b_, _+_E_n_t_r_y))
- Search for the given foreign library and link it to the current
- SWI-Prolog instance. The library may be specified with or without
- the extension. First, aabbssoolluuttee__ffiillee__nnaammee//33is used to locate
- the file. If this succeeds, the full path is passed to the
- low-level function to open the library. Otherwise, the plain
- library name is passed, exploiting the operating-system defined
- search mechanism for the shared library. The ffiillee__sseeaarrcchh__ppaatthh//22
- alias mechanism defines the alias foreign, which refers to the
- directories <_p_l_h_o_m_e>/lib/<_a_r_c_h>and <_p_l_h_o_m_e>/lib, in this order.
-
- If the library can be loaded, the function called _E_n_t_r_y will be
- called without arguments. The return value of the function is
- ignored.
-
- The _E_n_t_r_y function will normally call PPLL__rreeggiisstteerr__ffoorreeiiggnn(()) to
- declare functions in the library as foreign predicates.
-
-
- uunnllooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b))
- If the foreign library defines the function uninstall(), this
- function will be called without arguments and its return value is
- ignored. Next, aabboolliisshh//22 is used to remove all known foreign
- predicates defined in the library. Finally the library itself is
- detached from the process.
-
-
- ccuurrrreenntt__ffoorreeiiggnn__lliibbrraarryy((_-_L_i_b_, _-_P_r_e_d_i_c_a_t_e_s))
- Query the currently loaded foreign libraries and their predicates.
- _P_r_e_d_i_c_a_t_e_s is a list with elements of the form _M_o_d_u_l_e_:_H_e_a_d,
- indicating the predicates installed with PPLL__rreeggiisstteerr__ffoorreeiiggnn(())when
- the entry-point of the library was called.
-
- Figure 5.1 connects a Windows message-box using a foreign function.
- This example was tested using Windows NT and Microsoft Visual C++ 2.0.
-
- #include <windows.h>
- #include <SWI-Prolog.h>
-
- static foreign_t
- pl_say_hello(term_t to)
- { char *a;
-
- if ( PL_get_atom_chars(to, &a) )
- { MessageBox(NULL, a, "DLL test", MB_OK|MB_TASKMODAL);
-
- PL_succeed;
- }
-
- PL_fail;
- }
-
- install_t
- install()
- { PL_register_foreign("say_hello", 1, pl_say_hello, 0);
- }
-
- Figure 5.1: MessageBox() example in Windows NT
-
-
- 55..44..11 SSttaattiicc LLiinnkkiinngg
-
- Below is an outline of the files structure required for statically
- linking SWI-Prolog with foreign extensions. .../pl refers to the
- SWI-Prolog home directory (see ffeeaattuurree//22). <_a_r_c_h> refers to the
- architecture identifier that may be obtained using ffeeaattuurree//22.
-
- .../pl/runtime/<_a_r_c_h>/libpl.a SWI-Library
- .../pl/include/SWI-Prolog.h Include file
- .../pl/include/SWI-Stream.h Stream I/O include file
- .../pl/include/SWI-Exports Export declarations (AIX only)
- .../pl/include/stub.c Extension stub
-
- The definition of the foreign predicates is the same as for
- dynamic linking. Unlike with dynamic linking however, there is
- no initialisation function. Instead, the file .../pl/include/stub.c
- may be copied to your project and modified to define the foreign
- extensions. Below is stub.c, modified to link the lowercase example
- described later in this chapter:
-
- /* Copyright (c) 1991 Jan Wielemaker. All rights reserved.
- jan@swi.psy.uva.nl
-
- Purpose: Skeleton for extensions
- */
-
- #include <stdio.h>
- #include <SWI-Prolog.h>
-
- extern foreign_t pl_lowercase(term, term);
-
- PL_extension predicates[] =
- {
- /*{ "name", arity, function, PL_FA_<flags> },*/
-
- { "lowercase", 2 pl_lowercase, 0 },
- { NULL, 0, NULL, 0 } /* terminating line */
- };
-
- int
- main(int argc, char **argv)
- { PL_register_extensions(predicates);
-
- if ( !PL_initialise(argc, argv) )
- PL_halt(1);
-
- PL_install_readline(); /* delete if not required */
-
- PL_halt(PL_toplevel() ? 0 : 1);
- }
-
- Now, a new executable may be created by compiling this file and linking
- it to libpl.a from the runtime directory and the libraries required by
- both the extensions and the SWI-Prolog kernel. This may be done by
- hand, or using the plld utility described in secrefplld.
-
-
- 55..44..22 DDyynnaammiicc LLiinnkkiinngg bbaasseedd oonn llooaadd__ffoorreeiiggnn//[[22,,55]]
-
- The predicates below are considered obsolete. They are briefly
- described here for compatibility purposes. New code should use the
- predicates from the library(shlib).
-
-
- llooaadd__ffoorreeiiggnn((_+_F_i_l_e_, _+_E_n_t_r_y))
- Load a foreign file or list of files specified by _F_i_l_e. The
- files are searched for similar to ccoonnssuulltt//11. Except that the `.o'
- extension is used rather than `.pl'.
-
- _E_n_t_r_y defines the entry point of the resulting executable. The
- entry point will be called by Prolog to install the foreign
- predicates.
-
-
- llooaadd__ffoorreeiiggnn((_+_F_i_l_e_, _+_E_n_t_r_y_, _+_O_p_t_i_o_n_s_, _+_L_i_b_r_a_r_i_e_s_, _+_S_i_z_e))
- The first two arguments are identical to those of llooaadd__ffoorreeiiggnn//22.
- _O_p_t_i_o_n_s is (a list of) additional option to be given to the loader.
- The options are inserted just before the files. _L_i_b_r_a_r_i_e_s is (a
- list of) libraries to be passed to the loader. They are inserted
- just after the files. If _S_i_z_e is specified Prolog first assumes
- that the resulting executable will fit in _S_i_z_e bytes and do the
- loading in one pass.
-
-
- ffoorreeiiggnn__ffiillee((_?_F_i_l_e))
- Is true if _F_i_l_e is the absolute path name of a file loaded as
- foreign file.
-
-
- 55..55 IInntteerrffaaccee DDaattaa ttyyppeess
-
-
- 55..55..11 TTyyppee term_t:: aa rreeffeerreennccee ttoo aa PPrroolloogg tteerrmm
-
- The principal data-type is term_t. Type term_t is what Quintus calls
- QP_term_ref. This name indicates better what the type represents: it
- is a _h_a_n_d_l_e for a term rather than the term itself. Terms can only be
- represented and manipulated using this type, as this is the only safe
- way to ensure the Prolog kernel is aware of all terms referenced by
- foreign code and thus allows the kernel to perform garbage-collection
- and/or stack-shifts while foreign code is active, for example during a
- callback from C.
-
- A term reference is a C unsigned long, representing the offset of a
- variable on the Prolog environment-stack. A foreign function is passed
- term references for the predicate-arguments, one for each argument. If
- references for intermediate results are needed, such references may be
- created using PPLL__nneeww__tteerrmm__rreeff(())or PPLL__nneeww__tteerrmm__rreeffss(()). These references
- normally live till the foreign function returns control back to Prolog.
- Their scope can be explicitly limited using PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())and
- PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())/PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(()).
-
- A term_t always refers to a valid Prolog term (variable, atom, integer,
- float or compound term). A term lives either until backtracking
- takes us back to a point before the term was created, the garbage
- collector has collected the term or the term was created after a
- PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())and PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(())has been called.
-
- The foreign-interface functions can either _r_e_a_d, _u_n_i_f_y or _w_r_i_t_e to
- term-references. In the this document we use the following notation
- for arguments of type term_t:
-
- term_t +t Accessed in read-mode. The `+'
- indicates the argument is `input'.
- term_t -t Accessed in write-mode.
- term_t ?t Accessed in unify-mode.
-
- Term references are obtained in any of the following ways.
-
- o _P_a_s_s_e_d _a_s _a_r_g_u_m_e_n_t
- The C-functions implementing foreign predicates are passed their
- arguments as term-references. These references may be read or
- unified. Writing to these variables causes undefined behaviour.
-
- o _C_r_e_a_t_e_d _b_y PPLL__nneeww__tteerrmm__rreeff(())
- A term created by PPLL__nneeww__tteerrmm__rreeff(())is normally used to build
- temporary terms or be written by one of the interface functions.
- For example, PPLL__ggeett__aarrgg(())writes a reference to the term-argument in
- its last argument.
-
- o _C_r_e_a_t_e_d _b_y PPLL__nneeww__tteerrmm__rreeffss((_i_n_t _n))
- This function returns a set of term refs with the same
- characteristics as PPLL__nneeww__tteerrmm__rreeff(()). See PPLL__ooppeenn__qquueerryy(()).
-
- o _C_r_e_a_t_e_d _b_y PPLL__ccooppyy__tteerrmm__rreeff((_t_e_r_m___t _t))
- Creates a new term-reference to the same term as the argument. The
- term may be written to. See figure 5.3.
-
- Term-references can safely be copied to other C-variables of type
- term_t, but all copies will always refer to the same term.
-
-
- _t_e_r_m___t PPLL__nneeww__tteerrmm__rreeff(())
- Return a fresh reference to a term. The reference is allocated
- on the _l_o_c_a_l stack. Allocating a term-reference may trigger a
- stack-shift on machines that cannot use sparse-memory management
- for allocation the Prolog stacks. The returned reference describes
- a variable.
-
-
- _t_e_r_m___t PPLL__nneeww__tteerrmm__rreeffss((_i_n_t _n))
- Return _n new term references. The first term-reference is
- returned. The others are _t +1, _t +2, etc. There are two reasons
- for using this function. PPLL__ooppeenn__qquueerryy(())expects the arguments as
- a set of consecutive term references and _v_e_r_y time-critical code
- requiring a number of term-references can be written as:
-
- pl_mypredicate(term_t a0, term_t a1)
- { term_t t0 = PL_new_term_refs(2);
- term_t t1 = t0+1;
-
- ...
- }
-
-
- _t_e_r_m___t PPLL__ccooppyy__tteerrmm__rreeff((_t_e_r_m___t _f_r_o_m))
- Create a new term reference and make it point initially to the same
- term as _f_r_o_m. This function is commonly used to copy a predicate
- argument to a term reference that may be written.
-
-
- _v_o_i_d PPLL__rreesseett__tteerrmm__rreeffss((_t_e_r_m___t _a_f_t_e_r))
- Destroy all term references that have been created after _a_f_t_e_r,
- including _a_f_t_e_r itself. Any reference to the invalidated term
- references after this call results in undefined behaviour.
-
- Note that returning from the foreign context to Prolog will
- reclaim all references used in the foreign context. This call
- is only necessary if references are created inside a loop that
- never exits back to Prolog. See also PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(()),
- PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())and PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(()).
-
-
- 55..55..11..11 IInntteerraaccttiioonn wwiitthh tthhee ggaarrbbaaggee ccoolllleeccttoorr aanndd ssttaacckk--sshhiifftteerr
-
- Prolog implements two mechanisms for avoiding stack overflow: garbage
- collection and stack expansion. On machines that allow for it, Prolog
- will use virtual memory management to detect stack overflow and expand
- the runtime stacks. On other machines Prolog will reallocate the
- stacks and update all pointers to them. To do so, Prolog needs to know
- which data is referenced by C-code. As all Prolog data known by C is
- referenced through term references (term_t), Prolog has all information
- necessary to perform its memory management without special precautions
- from the C-programmer.
-
-
- 55..55..22 OOtthheerr ffoorreeiiggnn iinntteerrffaaccee ttyyppeess
-
- aattoomm__tt An atom in Prologs internal representation. Atoms are pointers
- to an opaque structure. They are a unique representation for
- represented text, which implies that atom A represents the same
- text as atom B if-and-only-if A and B are the same pointer.
-
- Atoms are the central representation for textual constants in
- Prolog The transformation of C a character string to an atom
- implies a hash-table lookup. If the same atom is needed often, it
- is advised to store its reference in a global variable to avoid
- repeated lookup.
-
- ffuunnccttoorr__tt A functor is the internal representation of a name/arity
- pair. They are used to find the name and arity of a compound term
- as well as to construct new compound terms. Like atoms they live
- for the whole Prolog session and are unique.
-
- pprreeddiiccaattee__tt Handle to a Prolog predicate. Predicate handles live
- forever (although they can loose their definition).
-
- qqiidd__tt Query Identifier. Used by
- PPLL__ooppeenn__qquueerryy(())/PPLL__nneexxtt__ssoolluuttiioonn(())/PPLL__cclloossee__qquueerryy(()) to handle back-
- tracking from C.
-
- ffiidd__tt Frame Identifier. Used by
- PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())/PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(()).
-
- mmoodduullee__tt A module is a unique handle to a Prolog module. Modules are
- used only to call predicates in a specific module.
-
- ffoorreeiiggnn__tt Return type for a C-function implementing a Prolog predicate.
-
- ccoonnttrrooll__tt Passed as additional argument to non-deterministic foreign
- functions. See PL_retry*() and PL_foreign_context*().
-
- iinnssttaallll__tt Type for the install() and uninstall() functions of shared or
- dynamic link libraries. See secrefshlib.
-
-
- 55..66 TThhee FFoorreeiiggnn IInncclluuddee FFiillee
-
-
- 55..66..11 AArrgguummeenntt PPaassssiinngg aanndd CCoonnttrrooll
-
- If Prolog encounters a foreign predicate at run time it will call
- a function specified in the predicate definition of the foreign
- predicate. The arguments 1;:::; <_a_r_i_t_y>pass the Prolog arguments to the
- goal as Prolog terms. Foreign functions should be declared of type
- foreign_t. Deterministic foreign functions have two alternatives to
- return control back to Prolog:
-
-
- _v_o_i_d PPLL__ssuucccceeeedd(())
- Succeed deterministically. PL_succeed is defined as return TRUE.
-
-
- _v_o_i_d PPLL__ffaaiill(())
- Fail and start Prolog backtracking. PL_fail is defined as
- return FALSE.
-
-
- 55..66..11..11 NNoonn--ddeetteerrmmiinniissttiicc FFoorreeiiggnn PPrreeddiiccaatteess
-
- By default foreign predicates are deterministic. Using the
- PL_FA_NONDETERMINISTIC attribute (see PPLL__rreeggiisstteerr__ffoorreeiiggnn(())) it is
- possible to register a predicate as a non-deterministic predicate.
- Writing non-deterministic foreign predicates is slightly more
- complicated as the foreign function needs context information for
- generating the next solution. Note that the same foreign function
- should be prepared to be simultaneously active in more than one
- goal. Suppose the natural_number_below_n/2 is a non-deterministic
- foreign predicate, backtracking over all natural numbers lower than the
- first argument. Now consider the following predicate:
-
- quotient_below_n(Q, N) :-
- natural_number_below_n(N, N1),
- natural_number_below_n(N, N2),
- Q =:= N1 / N2, !.
-
- In this predicate the function natural_number_below_n/2 simultaneously
- generates solutions for both its invocations.
-
- Non-deterministic foreign functions should be prepared to handle three
- different calls from Prolog:
-
- o _I_n_i_t_i_a_l _c_a_l_l _(PL_FIRST_CALL_)
- Prolog has just created a frame for the foreign function and asks
- it to produce the first answer.
-
- o _R_e_d_o _c_a_l_l _(PL_REDO_)
- The previous invocation of the foreign function associated with the
- current goal indicated it was possible to backtrack. The foreign
- function should produce the next solution.
-
- o _T_e_r_m_i_n_a_t_e _c_a_l_l _(PL_CUTTED_)
- The choice point left by the foreign function has been destroyed by
- a cut. The foreign function is given the opportunity to clean the
- environment.
-
- Both the context information and the type of call is provided
- by an argument of type control_t appended to the argument list
- for deterministic foreign functions. The macro PPLL__ffoorreeiiggnn__ccoonnttrrooll(())
- extracts the type of call from the control argument. The
- foreign function can pass a context handle using the PL_retry*()
- macros and extract the handle from the extra argument using the
- PL_foreign_context*() macro.
-
-
- _v_o_i_d PPLL__rreettrryy((_l_o_n_g))
- The foreign function succeeds while leaving a choice point. On
- backtracking over this goal the foreign function will be called
- again, but the control argument now indicates it is a `Redo' call
- and the macro PPLL__ffoorreeiiggnn__ccoonntteexxtt(())will return the handle passed via
- PPLL__rreettrryy(()). This handle is a 30 bits signed value (two bits are
- used for status indication).
-
-
- _v_o_i_d PPLL__rreettrryy__aaddddrreessss((_v_o_i_d _*))
- As PPLL__rreettrryy(()), but ensures an address as returned by malloc() is
- correctly recovered by PPLL__ffoorreeiiggnn__ccoonntteexxtt__aaddddrreessss(()).
-
-
- _i_n_t PPLL__ffoorreeiiggnn__ccoonnttrrooll((_c_o_n_t_r_o_l___t))
- Extracts the type of call from the control argument. The return
- values are described above. Note that the function should be
- prepared to handle the PL_CUTTED case and should be aware that the
- other arguments are not valid in this case.
-
-
- _l_o_n_g PPLL__ffoorreeiiggnn__ccoonntteexxtt((_c_o_n_t_r_o_l___t))
- Extracts the context from the context argument. In the call type
- is PL_FIRST_CALL the context value is 0L. Otherwise it is the value
- returned by the last PPLL__rreettrryy(()) associated with this goal (both if
- the call type is PL_REDO as PL_CUTTED).
-
-
- _v_o_i_d _* PPLL__ffoorreeiiggnn__ccoonntteexxtt__aaddddrreessss((_c_o_n_t_r_o_l___t))
- Extracts an address as passed in by PPLL__rreettrryy__aaddddrreessss(()).
-
- Note: If a non-deterministic foreign function returns using PL_succeed
- or PL_fail, Prolog assumes the foreign function has cleaned its
- environment. NNoo call with control argument PL_CUTTED will follow.
-
- The code of figure 5.2 shows a skeleton for a non-deterministic foreign
- predicate definition.
-
- typedef struct /* define a context structure */
- { ...
- } context;
-
- foreign_t
- my_function(term_t a0, term_t a1, foreign_t handle)
- { struct context * ctxt;
-
- switch( PL_foreign_control(handle) )
- { case PL_FIRST_CALL:
- ctxt = malloc(sizeof(struct context));
- ...
- PL_retry_address(ctxt);
- case PL_REDO:
-
- ctxt = PL_foreign_context_address(handle);
- ...
- PL_retry_address(ctxt);
- case PL_CUTTED:
- free(ctxt);
- PL_succeed;
- }
- }
-
- Figure 5.2: Skeleton for non-deterministic foreign functions
-
-
- 55..66..22 AAttoommss aanndd ffuunnccttoorrss
-
- The following functions provide for communication using atoms and
- functors.
-
-
- _a_t_o_m___t PPLL__nneeww__aattoomm((_c_o_n_s_t _c_h_a_r _*))
- Return an atom handle for the given C-string. This function always
- succeeds. The returned handle is valid for the entire session.
-
-
- _c_o_n_s_t _c_h_a_r _* PPLL__aattoomm__cchhaarrss((_a_t_o_m___t _a_t_o_m))
- Return a C-string for the text represented by the given atom. The
- returned text will not be changed by Prolog. It is not allowed to
- modify the contents, not even `temporary' as the string may reside
- in read-only memory.
-
-
- _f_u_n_c_t_o_r___t PPLL__nneeww__ffuunnccttoorr((_a_t_o_m___t _n_a_m_e_, _i_n_t _a_r_i_t_y))
- Returns a _f_u_n_c_t_o_r _i_d_e_n_t_i_f_i_e_r, a handle for the name/arity pair.
- The returned handle is valid for the entire Prolog session.
-
-
- _a_t_o_m___t PPLL__ffuunnccttoorr__nnaammee((_f_u_n_c_t_o_r___t _f))
- Return an atom representing the name of the given functor.
-
-
- _i_n_t PPLL__ffuunnccttoorr__aarriittyy((_f_u_n_c_t_o_r___t _f))
- Return the arity of the given functor.
-
-
- 55..66..33 AAnnaallyyssiinngg TTeerrmmss vviiaa tthhee FFoorreeiiggnn IInntteerrffaaccee
-
- Each argument of a foreign function (except for the control argument)
- is of type term_t, an opaque handle to a Prolog term. Three groups of
- functions are available for the analysis of terms. The first just
- validates the type, like the Prolog predicates vvaarr//11, aattoomm//11, etc and
- are called PL_is_*(). The second group attempts to translate the
- argument into a C primitive type. These predicates take a term_t and a
- pointer to the appropriate C-type and return TRUE or FALSE depending on
- successful or unsuccessful translation. If the translation fails, the
- pointed-to data is never modified.
-
-
- 55..66..33..11 TTeessttiinngg tthhee ttyyppee ooff aa tteerrmm
-
-
- _i_n_t PPLL__tteerrmm__ttyyppee((_t_e_r_m___t))
- Obtain the type of a term, which should be a term returned by
- one of the other interface predicates or passed as an argument.
- The function returns the type of the Prolog term. The type
- identifiers are listed below. Note that the extraction functions
- PL_ge_t*() also validate the type and thus the two sections below
- are equivalent.
-
- if ( PL_is_atom(t) )
- { char *s;
-
- PL_get_atom_chars(t, &s);
- ...;
- }
-
- or
-
- char *s;
- if ( PL_get_atom_chars(t, &s) )
- { ...;
- }
-
- ___________________________________________________________________
- | PL_VARIABLE |An unbound variable. The value of term|
- | |as such is a unique identifier for the|
-
- | |variable. |
- | PL_ATOM |A Prolog atom. |
- | PL_STRING |A Prolog string. |
- | PL_INTEGER |A Prolog integer. |
- | PL_FLOAT |A Prolog floating point number. |
- | PL_TERM |A compound term. Note that a list is a|
- |________________________|compound_term_.//22._______________________|
-
- The functions PL_is_<_t_y_p_e> are an alternative to PPLL__tteerrmm__ttyyppee(()). The test
- PPLL__iiss__vvaarriiaabbllee((_t_e_r_m))is equivalent to PPLL__tteerrmm__ttyyppee((_t_e_r_m))== PL_VARIABLE,
- but the first is considerably faster. On the other hand, using a
- switch over PPLL__tteerrmm__ttyyppee(())is faster and more readable then using an
- if-then-else using the functions below. All these functions return
- either TRUE or FALSE.
-
-
- _i_n_t PPLL__iiss__vvaarriiaabbllee((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is a variable.
-
-
- _i_n_t PPLL__iiss__aattoomm((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is an atom.
-
-
- _i_n_t PPLL__iiss__ssttrriinngg((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is a string.
-
-
- _i_n_t PPLL__iiss__iinntteeggeerr((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is an integer.
-
-
- _i_n_t PPLL__iiss__ffllooaatt((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is a float.
-
-
- _i_n_t PPLL__iiss__ccoommppoouunndd((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is a compound term.
-
-
- _i_n_t PPLL__iiss__ffuunnccttoorr((_t_e_r_m___t_, _f_u_n_c_t_o_r___t))
- Returns non-zero if _t_e_r_m is compound and its functor is _f_u_n_c_t_o_r.
- This test is equivalent to PPLL__ggeett__ffuunnccttoorr(()), followed by testing the
- functor, but easier to write and faster.
-
-
- _i_n_t PPLL__iiss__lliisstt((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is a compound term with functor ./2 or the
- atom [].
-
-
- _i_n_t PPLL__iiss__aattoommiicc((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is atomic (not variable or compound).
-
-
- _i_n_t PPLL__iiss__nnuummbbeerr((_t_e_r_m___t))
- Returns non-zero if _t_e_r_m is an integer or float.
-
-
- 55..66..33..22 RReeaaddiinngg ddaattaa ffrroomm aa tteerrmm
-
- The functions PL_get_*() read information from a Prolog term. Most of
- them take two arguments. The first is the input term and the second is
- a pointer to the output value or a term-reference.
-
-
- _i_n_t PPLL__ggeett__aattoomm((_t_e_r_m___t _+_t_, _a_t_o_m___t _*_a))
- If _t is an atom, store the unique atom identifier over _a. See also
- PPLL__aattoomm__cchhaarrss(())and PPLL__nneeww__aattoomm(()). If there is no need to access the
- data (characters) of an atom, it is advised to manipulate atoms
- using their handle.
-
-
- _i_n_t PPLL__ggeett__aattoomm__cchhaarrss((_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s))
- If _t is an atom, store a pointer to a 0-terminated C-string in _s.
- It is explicitly nnoott allowed to modify the contents of this string.
- Some built-in atoms may have the string allocated in read-only
- memory, so `temporary manipulation' can cause an error.
-
-
- _i_n_t PPLL__ggeett__ssttrriinngg((_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s_, _i_n_t _*_l_e_n))
- If _t is a string object, store a pointer to a 0-terminated
- C-string in _s and the length of the string in _l_e_n. Note that
- this pointer is invalidated by backtracking, garbage-collection and
- stack-shifts, so generally the only save operations are to pass it
- immediately to a C-function that doesn't involve Prolog.
-
-
- _i_n_t PPLL__ggeett__cchhaarrss((_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s_, _u_n_s_i_g_n_e_d _f_l_a_g_s))
- Convert the argument term _t to a 0-terminated C-string. _f_l_a_g_s is
- a bitwise disjunction from two groups of constants. The first
- specifies which term-types should converted and the second how the
- argument is stored. Below is a specification of these constants.
- BUF_RING implies, if the data is not static (as from an atom), the
- data is copied to the next buffer from a ring of four (4) buffers.
- This is a convenient way of converting multiple arguments passed to
- a foreign predicate to C-strings. If BUF_MALLOC is used, the data
- must be freed using free() when not needed any longer.
- ___________________________________________________________________
- | CVT_ATOM |Convert if term is an atom |
- | CVT_STRING |Convert if term is a string |
- | CVT_LIST |Convert if term is a list of integers|
- | |between 1 and 255 |
-
- | CVT_INTEGER |Convert if term is an integer (using %d) |
- | CVT_FLOAT |Convert if term is a float (using %f) |
- | CVT_NUMBER |Convert if term is a integer or float |
- | CVT_ATOMIC |Convert if term is atomic |
- | CVT_VARIABLE |Convert variable to print-name |
- | CVT_ALL |Convert if term is any of the above,|
- |________________________|except_for_variables_____________________|
- | BUF_DISCARDABLE |Data must copied immediately |
-
- | BUF_RING |Data is stored in a ring of buffers |
- | BUF_MALLOC |Data is copied to a new buffer returned||
- |________________________________________________|by__mmaalllloocc((3))__________________________________________________________||
-
-
- _i_n_t PPLL__ggeett__lliisstt__cchhaarrss((_+_t_e_r_m___t _l_, _c_h_a_r _*_*_s_, _u_n_s_i_g_n_e_d _f_l_a_g_s))
- Same as PPLL__ggeett__cchhaarrss((_l_, _s_, _C_V_T___L_I_S_T___f_l_a_g_s)), provided _f_l_a_g_s contains
- no of the CVT_* flags.
-
-
- _i_n_t PPLL__ggeett__iinntteeggeerr((_+_t_e_r_m___t _t_, _i_n_t _*_i))
- If _t is a Prolog integer, assign its value over _i. On 32-bit
- machines, this is the same as PPLL__ggeett__lloonngg(()), but avoids a warning
- from the compiler. See also PPLL__ggeett__lloonngg(()).
-
-
- _i_n_t PPLL__ggeett__lloonngg((_t_e_r_m___t _+_t_, _l_o_n_g _*_i))
- If _t is a Prolog integer, assign its value over _i. Note that
- Prolog integers have limited value-range. If _t is a floating point
- number that can be represented as a long, this function succeeds as
- well.
-
-
- _i_n_t PPLL__ggeett__ppooiinntteerr((_t_e_r_m___t _+_t_, _v_o_i_d _*_*_p_t_r))
- In the current system, pointers are represented by Prolog
- integers, but need some manipulation to make sure they do
- not get truncated due to the limited Prolog integer range.
- PPLL__ppuutt__ppooiinntteerr(())/PPLL__ggeett__ppooiinntteerr(())guarantees pointers in the range of
- malloc() are handled without truncating.
-
-
- _i_n_t PPLL__ggeett__ffllooaatt((_t_e_r_m___t _+_t_, _d_o_u_b_l_e _*_f))
- If _t is a float or integer, its value is assigned over _f.
-
-
- _i_n_t PPLL__ggeett__ffuunnccttoorr((_t_e_r_m___t _+_t_, _f_u_n_c_t_o_r___t _*_f))
- If _t is compound or an atom, the Prolog representation of
- the name-arity pair will be assigned over _f. See also
- PPLL__ggeett__nnaammee__aarriittyy(())and PPLL__iiss__ffuunnccttoorr(()).
-
-
- _i_n_t PPLL__ggeett__nnaammee__aarriittyy((_t_e_r_m___t _+_t_, _a_t_o_m___t _*_n_a_m_e_, _i_n_t _*_a_r_i_t_y))
- If _t is compound or an atom, the functor-name will be assigned
- over _n_a_m_e and the arity over _a_r_i_t_y. See also PPLL__ggeett__ffuunnccttoorr(())and
- PPLL__iiss__ffuunnccttoorr(()).
-
-
- _i_n_t PPLL__ggeett__mmoodduullee((_t_e_r_m___t _+_t_, _m_o_d_u_l_e___t _*_m_o_d_u_l_e))
- If _t is an atom, the system will lookup or create the corresponding
- module and assign an opaque pointer to it over _m_o_d_u_l_e,.
-
-
- _i_n_t PPLL__ggeett__aarrgg((_i_n_t _i_n_d_e_x_, _t_e_r_m___t _+_t_, _t_e_r_m___t _-_a))
- If _t is compound and index is between 1 and arity (including),
- assign _a with a term-reference to the argument.
-
-
- 55..66..33..33 RReeaaddiinngg aa lliisstt
-
- The functions from this section are intended to read a Prolog list from
- C. Suppose we expect a list of atoms, the following code will print the
- atoms, each on a line:
-
- foreign_t
- pl_write_atoms(term_t l)
- { term_t head = PL_new_term_ref(); /* variable for the elements */
- term_t list = PL_copy_term_ref(); /* copy as we need to write */
-
- while( PL_get_list(list, head, list) )
- { char *s;
-
- if ( PL_get_atom_chars(head, &s) )
- Sprintf("%s\n", s);
- else
- PL_fail;
- }
-
- return PL_get_nil(list); /* test end for [] */
- }
-
-
- _i_n_t PPLL__ggeett__lliisstt((_t_e_r_m___t _+_l_, _t_e_r_m___t _-_h_, _t_e_r_m___t _-_t))
- If _l is a list and not [] assign a term-reference to the head to _h
- and to the tail to _t.
-
-
- _i_n_t PPLL__ggeett__hheeaadd((_t_e_r_m___t _+_l_, _t_e_r_m___t _-_h))
- If _l is a list and not [] assign a term-reference to the head to _h.
-
-
- _i_n_t PPLL__ggeett__ttaaiill((_t_e_r_m___t _+_l_, _t_e_r_m___t _-_t))
- If _l is a list and not [] assign a term-reference to the tail to _t.
-
-
- _i_n_t PPLL__ggeett__nniill((_t_e_r_m___t _+_l))
- Succeeds if represents the atom [].
-
-
- 55..66..33..44 AAnn eexxaammppllee:: ddeeffiinniinngg ddiissppllaayy//11 iinn CC
-
- Figure 5.3 shows a definition of ddiissppllaayy//11 to illustrate the described
- functions.
- foreign_t
- pl_display(term_t t)
- { functor_t functor;
-
- int arity, len, n;
- char *s;
-
- switch( PL_term_type(t) )
- { case PL_VARIABLE:
- case PL_ATOM:
- case PL_INTEGER:
- case PL_FLOAT:
-
- PL_get_chars(t, &s, CVT_ALL);
- Sprintf("%s", s);
- break;
- case PL_STRING:
- PL_get_string_chars(t, &s, &len);
- Sprintf("\"%s\"", s);
- break;
-
- case PL_TERM:
- { term_t a = PL_new_term_ref();
-
- PL_get_name_arity(t, &name, &arity);
- Sprintf("%s(", PL_atom_chars(name));
- for(n=1; n<=arity; n++)
- { PL_get_arg(n, t, a);
- if ( n > 1 )
-
- Sprintf(", ");
- pl_display(a);
- }
- Sprintf(")");
- break;
- default:
- PL_fail; /* should not happen */
-
- }
-
- PL_succeed;
- }
-
- Figure 5.3: A Foreign definition of ddiissppllaayy//11
-
-
- 55..66..44 CCoonnssttrruuccttiinngg TTeerrmmss
-
- Terms can be constructed using functions from the PL_put_*() and
- PL_cons_*() families. This approach builds the term `inside-out',
- starting at the leaves and subsequently creating compound terms.
- Alternatively, terms may be created `top-down', first creating
- a compound holding only variables and subsequently unifying the
- arguments. This section discusses functions for the first approach.
- This approach is generally used for creating arguments for PPLL__ccaallll(()) and
- PL_open_query.
-
-
- _v_o_i_d PPLL__ppuutt__vvaarriiaabbllee((_t_e_r_m___t _-_t))
- Put a fresh variable in the term. The new variable lives on the
- global stack. Note that the initial variable lives on the local
- stack and is lost after a write to the term-references. After
- using this function, the variable will continue to live.
-
-
- _v_o_i_d PPLL__ppuutt__aattoomm((_t_e_r_m___t _-_t_, _a_t_o_m___t _a))
- Put an atom in the term reference from a handle. See also
- PPLL__nneeww__aattoomm(())and PPLL__aattoomm__cchhaarrss(()).
-
-
- _v_o_i_d PPLL__ppuutt__aattoomm__cchhaarrss((_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s))
- Put an atom in the term-reference constructed from the 0-terminated
- string. The string itself will never be references by Prolog after
- this function.
-
-
- _v_o_i_d PPLL__ppuutt__ssttrriinngg__cchhaarrss((_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s))
- Put a string in the term-reference. The data will be copied.
-
-
- _v_o_i_d PPLL__ppuutt__lliisstt__cchhaarrss((_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s))
- Put a list of ASCII values in the term-reference.
-
-
- _v_o_i_d PPLL__ppuutt__iinntteeggeerr((_t_e_r_m___t _-_t_, _l_o_n_g _i))
- Put a Prolog integer in the term reference.
-
-
- _v_o_i_d PPLL__ppuutt__ppooiinntteerr((_t_e_r_m___t _-_t_, _v_o_i_d _*_p_t_r))
- Put a Prolog integer in the term-reference. Provided ptr is in the
- `malloc()-area', PPLL__ggeett__ppooiinntteerr(())will get the pointer back.
-
-
- _v_o_i_d PPLL__ppuutt__ffllooaatt((_t_e_r_m___t _-_t_, _d_o_u_b_l_e _f))
- Put a floating-point value in the term-reference.
-
-
- _v_o_i_d PPLL__ppuutt__ffuunnccttoorr((_t_e_r_m___t _-_t_, _f_u_n_c_t_o_r___t _f_u_n_c_t_o_r))
- Create a new compound term from _f_u_n_c_t_o_r and bind _t to this term.
- All arguments of the term will be variables. To create a term with
- instantiated arguments, either instantiate the arguments using the
- PL_unify_*() functions or use PPLL__ccoonnss__ffuunnccttoorr(()).
-
-
- _v_o_i_d PPLL__ppuutt__lliisstt((_t_e_r_m___t _-_l))
- Same as PPLL__ppuutt__ffuunnccttoorr((_l_, _P_L___n_e_w___f_u_n_c_t_o_r_(_P_L___n_e_w___a_t_o_m_(_"_._")), 2)).
-
-
- _v_o_i_d PPLL__ppuutt__nniill((_t_e_r_m___t _-_l))
- Same as PPLL__ppuutt__aattoomm__cchhaarrss((_"_[_]_")).
-
-
- _v_o_i_d PPLL__ppuutt__tteerrmm((_t_e_r_m___t _-_t_1_, _t_e_r_m___t _+_t_2))
- Make _t_1 point to the same term as _t_2.
-
-
- _v_o_i_d PPLL__ccoonnss__ffuunnccttoorr((_t_e_r_m___t _-_h_, _f_u_n_c_t_o_r___t _f_, _._._.))
- Create a term, whose arguments are filled from variable argument
- list holding the same number of term_t objects as the arity of the
- functor. To create the term animal(gnu, 50), use:
-
- term_t a1 = PL_new_term_ref();
- term_t a2 = PL_new_term_ref();
- term_t t;
-
- PL_put_atom_chars(a1, "gnu");
- PL_put_integer(a2, 50);
- PL_cons_functor(t, PL_new_functor(PL_new_atom("animal"), 2),
- a1, a2);
-
- After this sequence, the term-references _a_1 and _a_2 may be used for
- other purposes.
-
-
- _v_o_i_d PPLL__ccoonnss__lliisstt((_t_e_r_m___t _-_l_, _t_e_r_m___t _+_h_, _t_e_r_m___t _+_t))
- Create a list (cons-) cell in _l from the head and tail. The code
- below creates a list of atoms from a char **. The list is built
- tail-to-head. The PL_unify_*() functions can be used to build a
- list head-to-tail.
-
- void
- put_list(term_t l, int n, char **words)
- { term_t a = PL_new_term_ref();
-
- PL_put_nil(l);
- while( --n >= 0 )
- { PL_put_atom_chars(a, words[n]);
- PL_put_list(l, a, l);
- }
- }
-
-
- 55..66..55 UUnniiffyyiinngg ddaattaa
-
- The functions of this sections _u_n_i_f_y terms with other terms or
- translated C-data structures. Except for PPLL__uunniiffyy(()), the functions of
- this section are specific to SWI-Prolog. They have been introduced
- to make translation of old code easier, but also because they provide
- for a faster mechanism for returning data to Prolog that requires less
- term-references. Consider the case where we want a foreign function to
- return the host name of the machine Prolog is running on. Using the
- PL_get_*() and PL_put_*() functions, the code becomes:
-
- foreign_t
- pl_hostname(term_t name)
- { char buf[100];
-
- if ( gethostname(buf, sizeof(buf)) )
- { term_t tmp = PL_new_term_ref();
-
- PL_put_atom_chars(tmp, buf);
- return PL_unify(name, buf);
- }
-
- PL_fail;
- }
-
- Using PPLL__uunniiffyy__aattoomm__cchhaarrss(()), this becomes:
-
- foreign_t
- pl_hostname(term_t name)
- { char buf[100];
-
- if ( gethostname(buf, sizeof(buf)) )
- return PL_unify_atom_chars(name, buf);
-
- PL_fail;
- }
-
-
- _i_n_t PPLL__uunniiffyy((_t_e_r_m___t _?_t_1_, _t_e_r_m___t _?_t_2))
- Unify two Prolog terms and return non-zero on success.
-
-
- _i_n_t PPLL__uunniiffyy__aattoomm((_t_e_r_m___t _?_t_, _a_t_o_m___t _a))
- Unify _t with the atom _a and return non-zero on success.
-
-
- _i_n_t PPLL__uunniiffyy__aattoomm__cchhaarrss((_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s))
- Unify _t with an atom created from _c_h_a_r_s and return non-zero on
- success.
-
-
- _i_n_t PPLL__uunniiffyy__lliisstt__cchhaarrss((_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s))
- Unify _t with a list of ASCII characters constructed from _c_h_a_r_s.
-
-
- _i_n_t PPLL__uunniiffyy__ssttrriinngg__cchhaarrss((_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s))
- Unify _t with a Prolog string object created from _c_h_a_r_s.
-
-
- _i_n_t PPLL__uunniiffyy__iinntteeggeerr((_t_e_r_m___t _?_t_, _l_o_n_g _n))
- Unify _t with a Prolog integer from _n.
-
-
- _i_n_t PPLL__uunniiffyy__ffllooaatt((_t_e_r_m___t _?_t_, _d_o_u_b_l_e _f))
- Unify _t with a Prolog float from _f.
-
-
- _i_n_t PPLL__uunniiffyy__ppooiinntteerr((_t_e_r_m___t _?_t_, _v_o_i_d _*_p_t_r))
- Unify _t with a Prolog integer describing the pointer. See also
- PPLL__ppuutt__ppooiinntteerr(())and PPLL__ggeett__ppooiinntteerr(()).
-
-
- _i_n_t PPLL__uunniiffyy__ffuunnccttoorr((_t_e_r_m___t _?_t_, _f_u_n_c_t_o_r___t _f))
- If _t is a compound term with the given functor, just succeed. If
- it is unbound, create a term and bind the variable, else fails.
- Not that this function does not create a term if the argument is
- already instantiated.
-
-
- _i_n_t PPLL__uunniiffyy__lliisstt((_t_e_r_m___t _?_l_, _t_e_r_m___t _-_h_, _t_e_r_m___t _-_t))
- Unify _l with a list-cell (./2). If successful, write a reference
- to the head of the list to _h and a reference to the tail of the
- list in _t. This reference may be used for subsequent calls to
- this function. Suppose we want to return a list of atoms from
- a char **. We could use the example described by PPLL__ppuutt__lliisstt(()),
- followed by a call to PPLL__uunniiffyy(()), or we can use the code below. If
- the predicate argument is unbound, the difference is minimal (the
- code based on PPLL__ppuutt__lliisstt(())is probably slightly faster). If the
- argument is bound, the code below may fail before reaching the end
- of the word-list, but even if the unification succeeds, this code
- avoids a duplicate (garbage) list and a deep unification.
-
- foreign_t
- pl_get_environ(term_t env)
- { term_t l = PL_copy_term_ref(env);
- term_t a = PL_new_term_ref();
- extern char **environ;
-
- while(*environ)
- { if ( !PL_unify_list(l, a, l) ||
- !PL_unify_atom_chars(a, *environ) )
- PL_fail;
- }
-
- return PL_unify_nil(l);
- }
-
-
- _i_n_t PPLL__uunniiffyy__nniill((_t_e_r_m___t _?_l))
- Unify _l with the atom [].
-
-
- _i_n_t PPLL__uunniiffyy__aarrgg((_i_n_t _i_n_d_e_x_, _t_e_r_m___t _?_t_, _t_e_r_m___t _?_a))
- Unifies the _i_n_d_e_x_-_t_h argument (1-based) of _t with _a.
-
-
- _i_n_t PPLL__uunniiffyy__tteerrmm((_t_e_r_m___t _?_t_, _._._.))
- Unify _t with a (normally) compound term. The remaining arguments
- is a sequence of a type identifier, followed by the required
- arguments. This predicate is an extension to the Quintus
- and SICStus foreign interface from which the SWI-Prolog foreign
- interface has been derived, but has proved to be a powerful and
- comfortable way to create compound terms from C. Due to the vararg
- packing/unpacking and the required type-switching this interface is
- slightly slower than using the primitives. Please note that some
- bad C-compilers have fairly low limits on the number of arguments
- that may be passed to a function.
-
- The type identifiers are:
-
- PL_VARIABLE nnoonnee
- No op. Used in arguments of PL_FUNCTOR.
-
- PL_ATOM aattoomm__tt
- Unify the argument with an atom, as in PPLL__uunniiffyy__aattoomm(()).
-
- PL_INTEGER lloonngg
- Unify the argument with an integer, as in PPLL__uunniiffyy__iinntteeggeerr(()).
-
- PL_FLOAT ddoouubbllee
- Unify the argument with a float, as in PPLL__uunniiffyy__ffllooaatt(()).
- Note that, as the argument is passed using the C vararg
- conventions, a float must be casted to a double explicitly.
-
- PL_STRING ccoonnsstt cchhaarr **
- Unify the argument with a string object, as in
- PPLL__uunniiffyy__ssttrriinngg__cchhaarrss(()).
-
- PL_TERM tteerrmm__tt
- Unify a subterm. Note this may the return value of a
- PPLL__nneeww__tteerrmm__rreeff(())call to get access to a variable.
-
- PL_CHARS ccoonnsstt cchhaarr **
- Unify the argument with an atom, constructed from the C char
- *, as in PPLL__uunniiffyy__aattoomm__cchhaarrss(()).
-
- PL_FUNCTOR ffuunnccttoorr__tt,, ......
- Unify the argument with a compound term. This specification
- should be followed by exactly as many specifications as the
- number of arguments of the compound term.
-
- PL_LIST iinntt lleennggtthh,, ......
- Create a list of the indicated length. The following
- arguments contain the elements of the list.
-
- For example, to unify an argument with the term language(dutch),
- the following skeleton may be used:
-
- static functor_t FUNCTOR_language1;
-
- static void
- init_constants()
- { FUNCTOR_language1 = PL_new_functor(PL_new_atom("language"), 1);
- }
-
- foreign_t
- pl_get_lang(term_t r)
- { return PL_unify_term(r,
- PL_FUNCTOR, FUNCTOR_language1,
- PL_CHARS, "dutch");
- }
-
- install_t
- install()
- { PL_register_foreign("get_lang", 1, pl_get_lang, 0);
- init_constants();
- }
-
-
- 55..66..66 CCaalllliinngg PPrroolloogg ffrroomm CC
-
- The Prolog engine can be called from C. There are to interfaces for
- this. For the first, a term is created that could be used as an
- argument to ccaallll//11 and next PPLL__ccaallll(()) is used to call Prolog. This
- system is simple, but does not allow to inspect the different answers
- to a non-deterministic goal and is relatively slow as the runtime
- system needs to find the predicate. The other interface is based on
- PPLL__ooppeenn__qquueerryy(()), PPLL__nneexxtt__ssoolluuttiioonn(())and PPLL__ccuutt__qquueerryy(())or PPLL__cclloossee__qquueerryy(()).
- This mechanism is more powerful, but also more complicated to use.
-
-
- 55..66..66..11 PPrreeddiiccaattee rreeffeerreenncceess
-
- This section discusses the functions used to communicate about
- predicates. Though a Prolog predicate may defined or not, redefined,
- etc., a Prolog predicate has a handle that is not destroyed, nor moved.
- This handle is known by the type predicate_t.
-
-
- _p_r_e_d_i_c_a_t_e___t PPLL__pprreedd((_f_u_n_c_t_o_r___t _f_, _m_o_d_u_l_e___t _m))
- Return a handle to a predicate for the specified name/arity in the
- given module. This function always succeeds, creating a handle for
- an undefined predicate if no handle was available.
-
-
- _p_r_e_d_i_c_a_t_e___t PPLL__pprreeddiiccaattee((_c_o_n_s_t _c_h_a_r _*_n_a_m_e_, _i_n_t _a_r_i_t_y_, _c_o_n_s_t _c_h_a_r_* _m_o_d_u_l_e))
-
- Same a PPLL__pprreedd(()), but provides a more convenient interface
- to the C-programmer.
-
-
- _v_o_i_d PPLL__pprreeddiiccaattee__iinnffoo((_p_r_e_d_i_c_a_t_e___t _p_, _a_t_o_m___t _*_n_, _i_n_t _*_a_, _m_o_d_u_l_e___t _*_m))
- Return information on the predicate _p. The name is stored over
- _n, the arity over _a, while _m receives the definition module.
- Note that the latter need not be the same as specified with
- PPLL__pprreeddiiccaattee(()). If the predicate was imported into the module
- given to PPLL__pprreeddiiccaattee(()), this function will return the module where
- the predicate was defined.
-
-
- 55..66..66..22 IInniittiiaattiinngg aa qquueerryy ffrroomm CC
-
- This section discusses the functions for creating and manipulating
- queries from C. Note that a foreign context can have at most one active
- query. This implies it is allowed to make strictly nested calls
- between C and Prolog (Prolog calls C, calls Prolog, calls C, etc.,
- but it is nnoott allowed to open multiple queries and start generating
- solutions for each of them by calling PPLL__nneexxtt__ssoolluuttiioonn(()). Be sure to
- call PPLL__ccuutt__qquueerryy(()) or PPLL__cclloossee__qquueerryy(())on any query you opened before
- opening the next or returning control back to Prolog.
-
-
- _q_i_d___t PPLL__ooppeenn__qquueerryy((_m_o_d_u_l_e___t _c_t_x_, _i_n_t _f_l_a_g_s_, _p_r_e_d_i_c_a_t_e___t _p_, _t_e_r_m___t _+_t_0))
-
- Opens a query and returns an identifier for it. This function
- always succeeds, regardless whether the predicate is defined or
- not. _c_t_x is the _c_o_n_t_e_x_t _m_o_d_u_l_e of the goal. When NULL, the
- context module of the calling context will be used, or user if
- there is no calling context (as may happen in embedded systems).
- Note that the context module only matters for _m_o_d_u_l_e___t_r_a_n_s_p_a_r_e_n_t
- predicates. See ccoonntteexxtt__mmoodduullee//11 and mmoodduullee__ttrraannssppaarreenntt//11. The _p
- argument specifies the predicate, and should be the result of a
- call to PPLL__pprreedd(()) or PPLL__pprreeddiiccaattee(()). Note that it is allowed to
- store this handle as global data and reuse it for future queries.
- The term-reference _t_0 is the first of a vector of term-references
- as returned by PPLL__nneeww__tteerrmm__rreeffss((_n)).
-
- The _f_l_a_g_s arguments provides some additional options concerning
- debugging and exception handling. It is a bitwise or of the
- following values:
-
- PL_Q_NORMAL
- Normal operation. The debugger inherits its settings from
- the environment. If an exception occurs that is not handled
- in Prolog, a message is printed and the tracer is started to
- debug the error.
-
- PL_Q_NODEBUG
- Switch off the debugger while executing the goal. This option
- is used by many calls to hook-predicates to avoid tracing the
- hooks. An example is pprriinntt//11 calling ppoorrttrraayy//11 from foreign
- code.
-
- PL_Q_CATCH_EXCEPTION
- If an exception is raised while executing the goal, do not
- report it, but make it available for PPLL__eexxcceeppttiioonn(()).
-
- PL_Q_PASS_EXCEPTION
- As PL_Q_CATCH_EXCEPTION, but do not invalidate the exception-
- term while calling PPLL__cclloossee__qquueerryy(()). This option is
- experimental.
-
- The example below opens a query to the predicate is_a/2 to find the
- ancestor of for some name.
-
- char *
- ancestor(const char *me)
- { term_t a0 = PL_new_term_refs(2);
- static predicate_t p;
-
- if ( !p )
- p = PL_predicate("is_a", 2, "database");
-
- PL_put_atom_chars(a0, me);
- PL_open_query(NULL, PL_Q_NORMAL, p, a0);
- ...
- }
-
-
- _i_n_t PPLL__nneexxtt__ssoolluuttiioonn((_q_i_d___t _q_i_d))
- Generate the first (next) solution for the given query. The return
- value is TRUE if a solution was found, or FALSE to indicate the
- query could not be proven. This function may be called repeatedly
- until it fails to generate all solutions to the query.
-
-
- _v_o_i_d PPLL__ccuutt__qquueerryy((_q_i_d))
- Discards the query, but does not delete any of the data created by
- the query. It just invalidate _q_i_d, allowing for a new call to
- PPLL__ooppeenn__qquueerryy(())in this context.
-
-
- _v_o_i_d PPLL__cclloossee__qquueerryy((_q_i_d))
- As PPLL__ccuutt__qquueerryy(()), but all data and bindings created by the query
- are destroyed.
-
-
- _i_n_t PPLL__ccaallll__pprreeddiiccaattee((_m_o_d_u_l_e___t _m_, _i_n_t _d_e_b_u_g_, _p_r_e_d_i_c_a_t_e___t _p_r_e_d_, _t_e_r_m___t _+_t_0))
-
- Shorthand for PPLL__ooppeenn__qquueerryy(()), PPLL__nneexxtt__ssoolluuttiioonn(()), PPLL__ccuutt__qquueerryy(()),
- generating a single solution. The arguments are the same as for
- PPLL__ooppeenn__qquueerryy(()), the return value is the same as PPLL__nneexxtt__ssoolluuttiioonn(()).
-
-
- _i_n_t PPLL__ccaallll((_t_e_r_m___t_, _m_o_d_u_l_e___t))
- Call term just like the Prolog predicate oonnccee//11. _T_e_r_m is called in
- the specified module, or in the context module if module_t = NULL.
- Returns TRUE if the call succeeds, FALSE otherwise. Figure 5.4
- shows an example to obtain the number of defined atoms. All checks
- are omitted to improve readability.
-
-
- 55..66..77 DDiissccaarrddiinngg DDaattaa
-
- The Prolog data created and term-references needed to setup the call
- and/or analyse the result can in most cases be discarded right after
- the call. PPLL__cclloossee__qquueerryy(())allows for destructing the data, while
- leaving the term-references. The calls below may be used to destroy
- term-references and data. See figure 5.4 for an example.
-
-
- _f_i_d___t PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())
- Created a foreign frame, holding a mark that allows the system
- to undo bindings and destroy data created after it as well as
- providing the environment for creating term-references. This
- function is called by the kernel before calling a foreign
- predicate.
-
-
- _v_o_i_d PPLL__cclloossee__ffoorreeiiggnn__ffrraammee((_f_i_d___t _i_d))
- Discard all term-references created after the frame was opened.
- All other Prolog data is retained. This function is called by the
- kernel whenever a foreign function returns control back to Prolog.
-
-
- _v_o_i_d PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee((_f_i_d___t _i_d))
- Same as PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(()), but also undo all bindings made
- since the open and destroy all Prolog data.
-
- It is obligatory to call either of the two closing functions to discard
- a foreign frame. Foreign frames may be nested.
-
- int
- count_atoms()
- { fid_t fid = PL_open_foreign_frame();
- term_t goal = PL_new_term_ref();
- term_t a1 = PL_new_term_ref();
- term_t a2 = PL_new_term_ref();
- functor_t s2 = PL_new_functor(PL_new_atom("statistics"), 2);
-
- int atoms;
-
- PL_put_atom_chars(a1, "atoms");
- PL_cons_functor(goal, s2, a1, a2);
- PL_call(goal, NULL); /* call it in current module */
-
- PL_get_integer(a2, &atoms);
- PL_discard_foreign_frame(fid);
-
- return atoms;
- }
-
- Figure 5.4: Calling Prolog
-
-
- 55..66..88 FFoorreeiiggnn CCooddee aanndd MMoodduulleess
-
- Modules are identified via a unique handle. The following functions
- are available to query and manipulate modules.
-
-
- _m_o_d_u_l_e___t PPLL__ccoonntteexxtt(())
- Return the module identifier of the context module of the currently
- active foreign predicate.
-
-
- _i_n_t PPLL__ssttrriipp__mmoodduullee((_t_e_r_m___t _+_r_a_w_, _m_o_d_u_l_e___t _*_m_, _t_e_r_m___t _-_p_l_a_i_n))
- Utility function. If _r_a_w is a term, possibly holding the module
- construct <_m_o_d_u_l_e>:<_r_e_s_t>this function will make _p_l_a_i_n a reference
- to <_r_e_s_t> and fill _m_o_d_u_l_e _* with <_m_o_d_u_l_e>. For further nested
- module constructs the inner most module is returned via _m_o_d_u_l_e
- _*. If _r_a_w is not a module construct _a_r_g will simply be put in
- _p_l_a_i_n. If _m_o_d_u_l_e _* is NULL it will be set to the context module.
- Otherwise it will be left untouched. The following example shows
- how to obtain the plain term and module if the default module is
- the user module:
-
- { module m = PL_new_module(PL_new_atom("user"));
- term_t plain = PL_new_term_ref();
-
- PL_strip_module(term, &m, plain);
- ...
-
-
- _a_t_o_m___t PPLL__mmoodduullee__nnaammee((_m_o_d_u_l_e___t))
- Return the name of _m_o_d_u_l_e as an atom.
-
-
- _m_o_d_u_l_e___t PPLL__nneeww__mmoodduullee((_a_t_o_m___t _n_a_m_e))
- Find an existing or create a new module with name specified by the
- atom _n_a_m_e.
-
-
- 55..66..99 PPrroolloogg eexxcceeppttiioonnss iinn ffoorreeiiggnn ccooddee
-
- This section discusses PPLL__eexxcceeppttiioonn(()) and PPLL__tthhrrooww(()), the interface
- functions to detect and generate Prolog exceptions from C-code.
- PPLL__tthhrrooww(())is similar to tthhrrooww//11, and may be used to return an exception
- from a foreign predicate. After calling PPLL__tthhrrooww(()), the function
- implementing a foreign predicate should return failure. If success is
- returned, the exception is simply discarded. Calling PPLL__tthhrrooww(()) outside
- the context of a function implementing a foreign predicate results in
- undefined behaviour.
-
- PPLL__eexxcceeppttiioonn(()) may be used after a call to PPLL__nneexxtt__ssoolluuttiioonn(())fails, and
- returns a term reference to an exception term if an exception was
- raised, and 0 otherwise.
-
- If a C-function, implementing a predicate calls Prolog and detects an
- exception using PPLL__eexxcceeppttiioonn(()), it can handle this exception, or return
- with the exception. Some caution is required though. It is nnoott
- allowed to call PPLL__cclloossee__qquueerryy(())or PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(())afterwards,
- as this will invalidate the exception term. Below is the code that
- calls a Prolog defined arithmetic function (see aarriitthhmmeetthhiicc__ffuunnccttiioonn//11).
-
- If PPLL__nneexxtt__ssoolluuttiioonn(()) succeeds, the result is analysed and translated
- to a number, after which the query is closed and all Prolog data
- created after PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())is destroyed. On the other hand,
- if PPLL__nneexxtt__ssoolluuttiioonn(())fails and if an exception was raised, just pass
- it. Otherwise generate an exception (PPLL__eerrrroorr(()) is an internal call
- for building the standard error terms and calling PPLL__tthhrrooww(())). After
- this, the Prolog environment should be discarded using PPLL__ccuutt__qquueerryy(())
- and PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())to avoid invalidating the exception term.
-
- static int
- prologFunction(ArithFunction f, term_t av, Number r)
- { int arity = f->proc->definition->functor->arity;
- fid_t fid = PL_open_foreign_frame();
- qid_t qid;
- int rval;
-
- qid = PL_open_query(NULL, PL_Q_NORMAL, f->proc, av);
-
- if ( PL_next_solution(qid) )
- { rval = valueExpression(av+arity-1, r);
- PL_close_query(qid);
- PL_discard_foreign_frame(fid);
- } else
- { term_t except;
-
- if ( (except = PL_exception(qid)) )
- { rval = PL_throw(except); /* pass exception */
- } else
- { char *name = stringAtom(f->proc->definition->functor->name);
-
- /* generate exception */
- rval = PL_error(name, arity-1, NULL, ERR_FAILED, f->proc);
- }
-
- PL_cut_query(qid); /* donot destroy data */
- PL_close_foreign_frame(fid); /* same */
- }
-
- return rval;
- }
-
-
- _i_n_t PPLL__tthhrrooww((_t_e_r_m___t _e_x_c_e_p_t_i_o_n))
- Generate an exception (as tthhrrooww//11) and return FALSE. Below is an
- example returning an exception from foreign predicate:
-
- foreign_t
- pl_hello(term_t to)
- { char *s;
-
- if ( PL_get_atom_chars(to, &s) )
- { Sprintf("Hello \"%s\"\n", s);
-
- PL_succeed;
- } else
- { term_t except = PL_new_term_ref();
-
- PL_unify_term(except,
- PL_FUNCTOR, PL_new_functor(PL_new_atom("type_error"), 2),
- PL_ATOM, "atom",
- PL_TERM, to);
-
- return PL_throw(except);
- }
- }
-
-
- _t_e_r_m___t PPLL__eexxcceeppttiioonn((_q_i_d___t _q_i_d))
- If PPLL__nneexxtt__ssoolluuttiioonn(()) fails, this can be due to normal failure
- of the Prolog call, or because an exception was raised using
- tthhrrooww//11. This function returns a handle to the exception term if
- an exception was raised, or 0 if the Prolog goal simply failed..
-
-
- 55..66..1100 MMiisscceellllaanneeoouuss
-
-
- _i_n_t PPLL__ccoommppaarree((_t_e_r_m___t _t_1_, _t_e_r_m___t _t_2))
- Compares two terms using the standard order of terms and returns
- -1, 0 or 1. See also ccoommppaarree//33.
-
-
- 55..66..1111 CCaattcchhiinngg SSiiggnnaallss ((SSooffttwwaarree IInntteerrrruuppttss))
-
- SWI-Prolog catches the Unix signals SIGINT, SIGFPE and SIGSEGV. To
- avoid problems with foreign code attempting to catch these signals
- foreign code should call PPLL__ssiiggnnaall(()) to install signal handlers rather
- than the Unix library function signal(). SWI-Prolog will always handle
- SIGINT itself. SIGFPE and SIGSEGV are passed to the foreign code
- handlers if Prolog did not expect that signal.
-
-
- _v_o_i_d _(_*_)_(_) PPLL__ssiiggnnaall((_s_i_g_, _f_u_n_c))
- This function should be used to install signal handlers rather
- than the Unix library function signal(). It ensures consistent
- signal handling between SWI-Prolog and the foreign code and
- reinstalls signal handlers if a state created with ssaavvee__pprrooggrraamm//11
- is restarted.
-
-
- 55..66..1122 EErrrroorrss aanndd wwaarrnniinnggss
-
- Two standard functions are available to print standard Prolog errors to
- the standard error stream.
-
-
- _i_n_t PPLL__wwaarrnniinngg((_f_o_r_m_a_t_, _a_1_, _._._.))
- Print an error message starting with `[WARNING: ', followed by
- the output from _f_o_r_m_a_t, followed by a `]' and a newline. Then
- start the tracer. _f_o_r_m_a_t and the arguments are the same as for
- pprriinnttff((2)). Always returns FALSE.
-
-
- 55..66..1133 EEnnvviirroonnmmeenntt CCoonnttrrooll ffrroomm FFoorreeiiggnn CCooddee
-
-
- _i_n_t PPLL__aaccttiioonn((_i_n_t_, _C___t_y_p_e))
- Perform some action on the Prolog system. _i_n_t describes the
- action, _C___t_y_p_e provides the argument if necessary. The actions are
- listed in table 5.1.
- ___________________________________________________________________
- | PL_ACTION_TRACE |Start Prolog tracer |
- | PL_ACTION_DEBUG |Switch on Prolog debug mode |
- | PL_ACTION_BACKTRACE |Print backtrace on current output|
- | |stream. The argument (an int) is the|
- | |number of frames printed. |
- | PL_ACTION_HALT |Halt Prolog execution. This action|
-
- | |should be called rather than Unix exit()|
- | |to give Prolog the opportunity to clean|
- | |up. This call does not return. |
- | PL_ACTION_ABORT |Generate a Prolog abort. This call does|
- | |not return. |
- | PL_ACTION_BREAK |Create a standard Prolog break environ-|
- | |ment. Returns after the user types|
- | |control-D. |
-
- | PL_ACTION_SYMBOLFILE |The argument (a char *) is considered|
- | |to be hold the symbolfile for further|
- | |incremental loading. Should be|
- | |called by user applications that perform|
- | |incremental loading as well and want to|
- |________________________|inform_Prolog_of_the_new_symbol_table.___|
-
- Table 5.1: PPLL__aaccttiioonn(())options
-
-
- 55..66..1144 QQuueerryyiinngg PPrroolloogg
-
-
- _C___t_y_p_e PPLL__qquueerryy((_i_n_t))
- Obtain status information on the Prolog system. The actual
- argument type depends on the information required. _i_n_t describes
- what information is wanted. The options are given in table 5.2.
- ___________________________________________________________________
- | PL_QUERY_ARGC |Return an integer holding the number of|
- | |arguments given to Prolog from Unix. |
- | PL_QUERY_ARGV |Return a char ** holding the argument|
- | |vector given to Prolog from Unix. |
- | PL_QUERY_SYMBOLFILE |Return a char * holding the current|
-
- | |symbol file of the running process. |
- | PL_QUERY_ORGSYMBOLFILE |Return the initial symbol file (before|
- | |loading) of Prolog. By setting the|
- | |symbol file to this value no name|
- | |clashes can occur with previously loaded|
- | |foreign files (but no symbols can be|
- | |shared with earlier loaded modules as|
- | |well). |
-
- | PL_MAX_INTEGER |Return a long, representing the maximal|
- | |integer value represented by Prolog's|
- | |tagged integers. |
- | PL_MIN_INTEGER |Return a long, represented the minimal|
- | |integer value. |
- | PL_QUERY_VERSION |Return a long, representing the version|
-
- | |as 10; 000M* +100m* +p, where M is the |
- | |major, m the minor version number and |
- | |p the patch-level. For example, 20717|
- |________________________|means_2.7.17.____________________________|
-
- Table 5.2: PPLL__qquueerryy(()) options
-
-
- 55..66..1155 RReeggiisstteerriinngg FFoorreeiiggnn PPrreeddiiccaatteess
-
-
- _i_n_t PPLL__rreeggiisstteerr__ffoorreeiiggnn((_n_a_m_e_, _a_r_i_t_y_, _f_u_n_c_t_i_o_n_, _f_l_a_g_s))
- Register a C-function to implement a Prolog predicate. After this
- call returns successfully a predicate with name _n_a_m_e (a char *) and
- arity _a_r_i_t_y (a C int) is created. When called in Prolog, Prolog
- will call _f_u_n_c_t_i_o_n. _f_l_a_g_s forms bitwise or'ed list of options for
- the installation. These are:
- ___________________________________________________________________
- | PL_FA_NOTRACE |Predicate cannot be seen in the tracer |
- | PL_FA_TRANSPARENT |Predicate is module transparent |
- | PL_FA_NONDETERMINISTIC |Predicate is non-deterministic. See|
- |________________________|also_PPLL__rreettrryy(())._________________________|
-
-
- _v_o_i_d PPLL__rreeggiisstteerr__eexxtteennssiioonnss((_P_L___e_x_t_e_n_s_i_o_n _*_e))
- Register foreign predicates from a table of structures. The type
- PL_extension is defined as:
-
- typedef struct _PL_extension
- { char *predicate_name; /* Name of the predicate */
- short arity; /* Arity of the predicate */
- pl_function_t function; /* Implementing functions */
- short flags; /* Or of PL_FA_... */
- } PL_extension;
-
- Here is an example of its usage:
-
- static PL_extension predicates[] = {
- { "foo", 1, pl_foo, 0 },
- { "bar", 2, pl_bar, PL_FA_NONDETERMINISTIC },
- { NULL, 0, NULL, 0 }
- };
-
- main(int argc, char **argv)
- { PL_register_extensions(predicates);
-
- if ( !PL_initialise(argc, argv) )
- PL_halt(1);
-
- ...
- }
-
- The function PPLL__rreeggiisstteerr__eexxtteennssiioonnss(())is the only PL_* function that
- may be called bbeeffoorree PPLL__iinniittiiaalliissee(()). The functions are registered
- after registration of the SWI-Prolog builtin foreign predicates
- and before loading the initial saved state. This implies that
- iinniittiiaalliizzaattiioonn//11 directives can refer to them.
-
-
- 55..66..1166 FFoorreeiiggnn CCooddee HHooookkss
-
- For various specific applications some hooks re provided.
-
-
- _P_L___d_i_s_p_a_t_c_h___h_o_o_k___t PPLL__ddiissppaattcchh__hhooookk((_P_L___d_i_s_p_a_t_c_h___h_o_o_k___t))
- If this hook is not NULL, this function is called when reading
- from the terminal. It is supposed to dispatch events when
- SWI-Prolog is connected to a window environment. It can return
- two values: PL_DISPATCH_INPUT indicates Prolog input is available
- on file descriptor 0 or PL_DISPATCH_TIMEOUT to indicate a timeout.
- The old hook is returned. The type PL_dispatch_hook_t is defined
- as:
-
- typedef int (*PL_dispatch_hook_t)(void);
-
-
- _v_o_i_d PPLL__aabboorrtt__hhooookk((_P_L___a_b_o_r_t___h_o_o_k___t))
- Install a hook when aabboorrtt//00 is executed. SWI-Prolog aabboorrtt//00 is
- implemented using C setjmp()/longjmp() construct. The hooks are
- executed in the reverse order of their registration after the
- longjmp() took place and before the Prolog toplevel is reinvoked.
- The type PL_abort_hook_t is defined as:
-
- typedef void (*PL_abort_hook_t)(void);
-
-
- _i_n_t PPLL__aabboorrtt__uunnhhooookk((_P_L___a_b_o_r_t___h_o_o_k___t))
- Remove a hook installed with PPLL__aabboorrtt__hhooookk(()). Returns FALSE if no
- such hook is found, TRUE otherwise.
-
-
- _v_o_i_d PPLL__rreeiinniitt__hhooookk((_P_L___r_e_i_n_i_t___h_o_o_k___t))
- Install a hook that is called when a saved program (using
- ssaavvee__pprrooggrraamm//[[11,,22]]) is restored. The hooks are called in reverse
- order. The type PL_reinit_hook_t is defined as:
-
- typedef void (*PL_reinit_hook_t)(int argc, char **argv);
-
-
- _i_n_t PPLL__rreeiinniitt__uunnhhooookk((_P_L___r_e_i_n_i_t___h_o_o_k___t))
- Remove a hook installed with PPLL__rreeiinniitt__hhooookk(()). Returns FALSE if no
- such hook is found, TRUE otherwise.
-
-
- 55..66..1177 EEmmbbeeddddiinngg SSWWII--PPrroolloogg iinn aa CC--pprrooggrraamm
-
- As of version 2.1.0, SWI-Prolog may be embedded in a C-program.
- To reach at a compiled C-program with SWI-Prolog as an embedded
- application is very similar to creating a statically linked SWI-Prolog
- executable as described in section 5.4.1.
-
- The file .../pl/include/stub.c defines SWI-Prologs default main
- program:
-
- int
- main(int argc, char **argv)
- { if ( !PL_initialise(argc, argv) )
- PL_halt(1);
-
- PL_install_readline(); /* delete if you don't want readline */
-
- PL_halt(PL_toplevel() ? 0 : 1);
- }
-
- This may be replaced with your own main C-program. The interface
- function PPLL__iinniittiiaalliissee(()) mmuusstt be called before any of the other
- SWI-Prolog foreign language functions described in this chapter.
- PPLL__iinniittiiaalliissee(()) interprets all the command-line arguments, except for
- the -t toplevel flag that is interpreted by PPLL__ttoopplleevveell(()).
-
-
- _i_n_t PPLL__iinniittiiaalliissee((_i_n_t _a_r_g_c_, _c_h_a_r _*_*_a_r_g_v_, _c_h_a_r _*_*_e_n_v_i_r_o_n))
- Initialises the SWI-Prolog heap and stacks, restores the boot QLF
- file, loads the system and personal initialisation files, runs the
- aatt__iinniittiiaalliizzaattiioonn//11 hooks and finally runs the -g goal hook.
-
- PPLL__iinniittiiaalliissee(()) returns 1 if all initialisation succeeded and 0
- otherwise. Various fatal errors may cause PL_initialise to call
- PPLL__hhaalltt((_1)), preventing it from returning at all.
-
-
- _v_o_i_d PPLL__iinnssttaallll__rreeaaddlliinnee(())
- Installs the GNU-readline line-editor. Embedded applications that
- do not use the Prolog toplevel should normally delete this line,
- shrinking the Prolog kernel significantly.
-
-
- _i_n_t PPLL__ttoopplleevveell(())
- Runs the goal of the -t toplevel switch (default pprroolloogg//00) and
- returns 1 if successful, 0 otherwise.
-
-
- _v_o_i_d PPLL__hhaalltt((_i_n_t _s_t_a_t_u_s))
- Cleanup the Prolog environment and calls exit() with the status
- argument.
-
-
- 55..77 LLiinnkkiinngg eemmbbeeddddeedd aapppplliiccaattiioonnss uussiinngg pplllldd
-
- The utility program plld (Win32: plld.exe) may be used to link a
- combination of C-files and Prolog files into a stand-alone executable.
- plld automates most of what is described in the previous sections.
-
- In the normal usage, a copy is made of the default embedding
- template .../pl/include/stub.c. The main() routine is modified to
- suit your application. PPLL__iinniittiiaalliissee(())mmuusstt be passed the program-name
- (_a_r_g_v_[_0_]) (Win32: the executing program can be obtained using
- GGeettMMoodduulleeFFiilleeNNaammee(())). The other elements of the command-line may be
- modified. Next, plld is typically invoked as:
-
- plld -o output stubfile.c [other-c-or-o-files] [plfiles]
-
- plld will first split the options into various groups for both the
- C-compiler and the Prolog compiler. Next, it will add various default
- options to the C-compiler and call it to create an executable holding
- the user's C-code and the Prolog kernel. Then, it will call the
- SWI-Prolog compiler to create a saved state from the provided Prolog
- files and finally, it will attach this saved state to the created
- emulator to create the requested executable.
-
- Below, it is described how the options are split and which additional
- options are passed.
-
- --hheellpp
- Print brief synopsis.
-
- --ppll _p_r_o_l_o_g
- Select the prolog to use. This prolog is used for two purposes:
- get the home-directory as well as the compiler/linker options and
- create a saved state of the Prolog code.
-
- --lldd _l_i_n_k_e_r
- Linker used to link the raw executable. Default is to use the
- C-compiler (Win32: link.exe).
-
- --cccc _C_-_c_o_m_p_i_l_e_r
- Compiler for .c files found on the commandline. Default is the
- compiler used to build SWI-Prolog (see ffeeaattuurree//22) (Win32: cl.exe).
-
- --cc++++ _C_+_+_-_c_o_m_p_i_l_e_r
- Compiler for C++ sources (extensions .cpp, .cxx, .cc or .C) files
- found on the commandline. Default is c++ or g++ if the C-compiler
- is gcc) (Win32: cl.exe).
-
- --nnoossttaattee
- Just relink the kernel, do not add any Prolog code to the
- new kernel. This is used to create a new kernel holding
- additional foreign predicates on machines that do not support the
- shared-library (DLL) interface, or if building the state cannot be
- handled by the default procedure used by plld. In the latter case
- the state is created seperately and appended to the kernel using
- cat <_k_e_r_n_e_l> <_s_t_a_t_e> > <_o_u_t>(Win32: copy /b <_k_e_r_n_e_l>+<_s_t_a_t_e> <_o_u_t>)
-
- --ppll--ooppttiioonnss _,_._._.
- Additional options passed to Prolog when creating the saved state.
- The first character immediately following pl-options is used as
- separator and translated to spaces when the argument is built.
- Example: -pl-options,-F,xpce passed -F xpce as additional flags to
- Prolog.
-
- --lldd--ooppttiioonnss _,_._._.
- Passes options to the linker, similar to -pl-options.
-
- --cccc--ooppttiioonnss _,_._._.
- Passes options to the C/C++ compiler, similar to -pl-options.
-
- --vv
- Select verbose operation, showing the various programs and their
- options.
-
- --oo _o_u_t_f_i_l_e
- Reserved to specify the final output file.
-
- --ll_l_i_b_r_a_r_y
- Specifies a library for the C-compiler. By default, -lpl (Win32:
- libpl.lib) and the libraries needed by the Prolog kernel are given.
-
- --LL_l_i_b_r_a_r_y_-_d_i_r_e_c_t_o_r_y
- Specifies a library directory for the C-compiler. By default
- the directory containing the Prolog C-library for the current
- architecture is passed.
-
- -g | -Iinclude-directory | -Ddefinition
- These options are passed to the C-compiler. By default, the
- include directory containing SWI-Prolog.h is passed. plld adds two
- additional * -Ddef flags:
-
- --DD____SWI_PROLOG__
- Indicates the code is to be connected to SWI-Prolog.
-
- --DD____SWI_EMBEDDED__
- Indicates the creation of an embedded program.
-
- _*_._o | _*_._c | _*_._C | _*_._c_x_x | _*_._c_p_p
- Passed as input files to the C-compiler
-
- _*_._p_l |_*_._q_l_f
- Passed as input files to the Prolog compiler to create the
- saved-state.
-
- *
- I.e. all other options. These are passed as linker options to the
- C-compiler.
-
-
- 55..77..11 AA ssiimmppllee eexxaammppllee
-
- The following is a very simple example going through all the steps
- outlined above. It provides an arithmetic expression evaluator. We
- will call the application calc and define it in the files calc.c and
- calc.pl. The Prolog file is simple:
-
- calc(Atom) :-
- term_to_atom(Expr, Atom),
- A is Expr,
- write(A),
- nl.
-
- The C-part of the application parses the command-line options,
- initialises the Prolog engine, locates the calc/1 predicate and calls
- it. The coder is in figure 5.5.
-
- #include <stdio.h>
- #include <SWI-Prolog.h>
-
- PL_extension PL_extensions [] =
- {
-
- /*{ "name", arity, function, PL_FA_<flags> },*/
-
- { NULL, 0, NULL, 0 } /* terminating line */
- };
-
- #define MAXLINE 1024
-
- int
- main(int argc, char **argv)
- { char expression[MAXLINE];
- char *e = expression;
- char *program = argv[0];
- char *plav[2];
- int n;
-
- /* combine all the arguments in a single string */
-
- for(n=1; n<argc; n++)
- { if ( n != 1 )
- *e++ = ' ';
- strcpy(e, argv[n]);
- e += strlen(e);
-
- }
-
- /* make the argument vector for Prolog */
-
- plav[0] = program;
- plav[1] = NULL;
-
- /* initialise Prolog */
-
- if ( !PL_initialise(1, plav) )
- PL_halt(1);
-
- /* Lookup calc/1 and make the arguments and call */
-
- { predicate_t pred = PL_predicate("calc", 1, "user");
-
- term_t h0 = PL_new_term_refs(1);
- int rval;
-
- PL_put_atom_chars(h0, expression);
- rval = PL_call_predicate(NULL, FALSE, pred, h0);
-
- PL_halt(rval ? 0 : 1);
-
- }
-
- return 0;
- }
-
- Figure 5.5: C-source for the calc application
-
- The application is now created using the following command-line:
-
- % plld -o calc calc.c calc.pl
-
- The following indicates the usage of the application:
-
- % calc pi/2
- 1.5708
-
-
- 55..88 EExxaammppllee ooff UUssiinngg tthhee FFoorreeiiggnn IInntteerrffaaccee
-
- Below is an example showing all stages of the declaration of a foreign
- predicate that transforms atoms possibly holding uppercase letters into
- an atom only holding lower case letters. Figure 5.6 shows the C-source
- file, figure 5.7 illustrates compiling and loading of foreign code.
- /* Include file depends on local installation */
-
- #include <SWI-Prolog.h>
- #include <stdlib.h>
- #include <ctype.h>
-
- foreign_t
- pl_lowercase(term_t u, term_t l)
- { char *copy;
- char *s, *q;
-
- int rval;
-
- if ( !PL_get_atom_chars(u, &s) )
- return PL_warning("lowercase/2: instantiation fault");
- copy = malloc(strlen(s)+1);
-
- for( q=copy; *s; q++, s++)
-
- *q = (isupper(*s) ? tolower(*s) : *s);
- *q = '\0';
-
- rval = PL_unify_atom_chars(l, copy);
- free(copy);
-
- return rval;
- }
-
- install_t
- install()
- { PL_register_foreign("lowercase", 2, pl_lowercase, 0);
- }
-
- Figure 5.6: Lowercase source file
-
- % gcc -I/usr/local/lib/pl-\plversion/include -fpic -c lowercase.c
- % gcc -shared -o lowercase.so lowercase.o
-
- % pl
- Welcome to SWI-Prolog (Version \plversion)
- Copyright (c) 1993-1996 University of Amsterdam. All rights reserved.
-
- For help, use ?- help(Topic). or ?- apropos(Word).
-
- 1 ?- load_foreign_library(lowercase).
-
- Yes
- 2 ?- lowercase('Hello World!', L).
-
- L = 'hello world!'
-
- Yes
-
- Figure 5.7: Compiling the C-source and loading the object file
-
-
- 55..99 NNootteess oonn UUssiinngg FFoorreeiiggnn CCooddee
-
-
- 55..99..11 MMeemmoorryy AAllllooccaattiioonn
-
- SWI-Prolog's memory allocation is based on the mmaalllloocc((3)) library
- routines. Foreign applications can safely use mmaalllloocc((3)), rreeaalllloocc((3))
- and ffrreeee((3)). Memory allocation using bbrrkk((2)) or ssbbrrkk((2)) is not allowed
- as these calls conflict with mmaalllloocc((3)).
-
-
- 55..99..22 DDeebbuuggggiinngg FFoorreeiiggnn CCooddee
-
- Statically linked foreign code or embedded systems can be debugged
- normally. Most modern environments provide debugging tools for
- dynamically loaded shared objects or dynamic load libraries. The
- following example traces the code of lowercase using ggddbb((1)) in a Unix
- environment.
-
- % gcc -I/usr/local/lib/pl-2.2.0/include -fpic -c -g lowercase.c
- % gcc -shared -o lowercase.so lowercase.o
- % gdb pl
- (gdb) r
- Welcome to SWI-Prolog (Version \plversion)
- Copyright (c) 1993-1996 University of Amsterdam. All rights reserved.
-
- For help, use ?- help(Topic). or ?- apropos(Word).
-
- ?- load_foreign_library(lowercase).
- <type Control-C>
- (gdb) shared % loads symbols for shared objects
- (gdb) break pl_lowercase
- (gdb) continue
- ?- lowercase('HELLO', X).
-
-
- 55..99..33 NNaammee CCoonnfflliiccttss iinn CC mmoodduulleess
-
- In the current version of the system all public C functions of
- SWI-Prolog are in the symbol table. This can lead to name clashes with
- foreign code. Someday I should write a program to strip all these
- symbols from the symbol table (why does Unix not have that?). For now
- I can only suggest to give your function another name. You can do this
- using the C preprocessor. If---for example---your foreign package uses
- a function warning(), which happens to exist in SWI-Prolog as well, the
- following macro should fix the problem.
-
- #define warning warning_
-
- Note that shared libraries do not have this problem as the shared
- library loader will only look for symbols in the main executable for
- symbols that are not defined in the library itself.
-
-
- 55..99..44 CCoommppaattiibbiilliittyy ooff tthhee FFoorreeiiggnn IInntteerrffaaccee
-
- The term-reference mechanism was first used by Quintus Prolog version
- 3. SICStus Prolog version 3 is strongly based on the Quintus
- interface. The described SWI-Prolog interface is similar to using the
- Quintus or SICStus interfaces, defining all foreign-predicate arguments
- of type +term. SWI-Prolog explicitly uses type functor_t, while
- Quintus and SICStus uses <_n_a_m_e> and <_a_r_i_t_y>. As the names of the
- functions differ from Prolog to Prolog, a simple macro layer dealing
- with the names can also deal with this detail. For example:
-
- #define QP_put_functor(t, n, a) PL_put_functor(t, PL_new_functor(n, a))
-
- The PL_unify_*() functions are lacking from the Quintus and SICStus
- interface. They can easily be emulated or the put/unify approach
- should be used to write compatible code.
-
- The PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())/PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())combination is lacking
- from both other Prologs. SICStus has PPLL__nneeww__tteerrmm__rreeffss((_0)), followed by
- PPLL__rreesseett__tteerrmm__rreeffss(())that allows for discarding term references.
-
- The Prolog interface for the graphical user interface package XPCE
- shares about 90% of the code using a simple macro layer to deal with
- different naming and calling conventions of the interfaces.
-
-
- CChhaapptteerr 66.. GGEENNEERRAATTIINNGG RRUUNNTTIIMMEE AAPPPPLLIICCAATTIIOONNSS
-
- This chapter describes the features of SWI-Prolog for delivering
- applications that can run without the development version of the system
- installed.
-
- A SWI-Prolog built application consists of at least two parts: the
- emulator and the compiled application. The latter is in the same
- format as a SWI-Prolog boot-file and SWI-Prolog pre-compiled (QLF)
- file. This format is fast loadable and abstracted just far enough
- to be machine independent. This implies an application delivered
- in binary format can run on any computer for which an emulator is
- available without modification.
-
-
- qqssaavvee__pprrooggrraamm((_+_F_i_l_e_, _+_L_i_s_t_O_f_O_p_t_i_o_n_s))
- Saves the current state of the program to the file _F_i_l_e. The
- result is an executable shell-script, that will start the emulator.
- _L_i_s_t_O_f_O_p_t_i_o_n_s is a list of <_K_e_y>=<_V_a_l_u_e> or <_K_e_y>(<_V_a_l_u_e>) pairs.
- The available keys are described in table 6.1.
- _______________________________________________________________________
- |__KKeeyy________________||OOppttiioonn__||________TTyyppee__________||DDeessccrriippttiioonn______________________________________________||__
- || local | --LL || K-bytes |Size (Limit) of local stack |
- | global | --GG || K-bytes |Size (Limit) of global stack |
- | trail | --TT || K-bytes |Size (Limit) of trail stack |
- | argument | --AA || K-bytes |Size (Limit) of argument stack |
-
- | goal | --gg || atom |Initialisation goal |
- | toplevel | --tt || atom |Prolog toplevel goal |
- |_init_file___|--ff___||_____atom_____|Personal_initialisation_file______|_
- | autoload | | bool |If true, run aauuttoollooaadd//00 first |
- | map | | atom |File containing info on dump |
- | op | |save/standard |Save operator declarations? |
- |_stand_alone_|_____|_____bool_____|Include_the_emulator_in_the_state_|_
-
- Table 6.1: <_K_e_y> = <_V_a_l_u_e> pairs for qqssaavvee__pprrooggrraamm//22
-
- The /bin/sh script contains the following data:
-
- 1. The _s_h_e_l_l _s_c_r_i_p_t _h_e_a_d_e_r starts as:
-
- #!/bin/sh
- #SAVE-VERSION=<num>
- #PROLOG-VERSION=<num>
- exec ${SWIPL-/path-to-emulator} -x $0 "$@"
-
- 2. The _s_e_t_t_i_n_g_s _s_e_c_t_i_o_n contains the default values for the
- various command line options.
-
- 3. The _p_r_e_d_i_c_a_t_e_s _s_e_c_t_i_o_n contains all predicates from the
- currently running system. Clauses of predicates defined as
- _v_o_l_a_t_i_l_e (see vvoollaattiillee//11) are nnoott saved. Neither are foreign
- predicates (see also below).
-
- 4. The _r_e_c_o_r_d _s_e_c_t_i_o_n contains the database records saved with
- rreeccoorrddaa//33 and friends. The current version saves records
- using directives.
-
- 5. The _f_l_a_g _s_e_c_t_i_o_n contains the global flags saved using the
- ffllaagg//33 predicate. Flags are saved as directives.
-
- 6. The _f_e_a_t_u_r_e _s_e_c_t_i_o_n contains all features that do not
- originate from the emulator itself. See sseett__ffeeaattuurree//22.
-
- 7. The _i_m_p_o_r_t _s_e_c_t_i_o_n contains the imports as far as they are
- not handled by the auto-import system. That is, an import
- is stored if the module is user or the module user contains
- a different definition as the one imported in the target
- module.'
-
- Before writing the data to file, qqssaavvee__pprrooggrraamm//22 will run
- aauuttoollooaadd//00 to all required autoloading the system can discover.
- See aauuttoollooaadd//00.
-
- Provided the application does not require any of the Prolog
- libraries to be loaded at runtime, the only file from the
- SWI-Prolog development environment required is the emulator itself.
- The emulator may be built in two flavours. The default is the
- _d_e_v_e_l_o_p_m_e_n_t _e_m_u_l_a_t_o_r. The _r_u_n_t_i_m_e _e_m_u_l_a_t_o_r is similar, but lacks
- the tracer. The stand-alone program cchhppll((1)) may be used to change
- the default path to the emulator.
-
- If the option stand_alone(on)is present, the emulator is prepended
- for the state. If the emulator is started and no state is
- specified using the -x flag, it will test whether a boot-file
- (state) is attached to the emulator itself and load this state.
- Provided the application has all libraries loaded, the resulting
- file may be started anywhere.
-
-
- qqssaavvee__pprrooggrraamm((_+_F_i_l_e))
- Equivalent to qsave_program(File, []).
-
-
- aauuttoollooaadd
- Check the current Prolog program for predicates that are referred
- to, are undefined and have a definition in the Prolog library.
- Load the appropriate libraries.
-
- This predicate is used by qqssaavvee__pprrooggrraamm//[[11,,22]] to ensure the saved
- state will not depend on one of the libraries. The predicate
- aauuttoollooaadd//00 will find all ddiirreecctt references to predicates. It does
- not find predicates referenced via meta-predicates. The predicate
- log/2 is defined in the library(quintus) to provide a quintus
- compatible means to compute the natural logarithm of a number. The
- following program will behave correctly if its state is executed in
- an environment where the library(quintus) is not available:
-
- logtable(From, To) :-
- From > To, !.
- logtable(From, To) :-
- log(From, Value),
- format('~d~t~8|~2f~n', [From, Value]),
- F is From + 1,
- logtable(F, To).
-
- However, the following implementation refers to log/2 through the
- meta-predicate mmaapplliisstt//33. Autoload will not be able to find the
- reference. This problem may be fixed either by loading the module
- libtary(quintus) explicitly or use rreeqquuiirree//11 to tell the system
- that the predicate log/2 is required by this module.
-
- logtable(From, To) :-
- findall(X, between(From, To, X), Xlist),
- maplist(log, Xlist, SineList),
- write_table(Xlist, SineList).
-
- write_table([], []).
- write_table([I|IT], [V|VT]) :-
- format('~d~t~8|~2f~n', [I, V]),
- write_table(IT, VT).
-
-
- vvoollaattiillee _+_N_a_m_e_/_A_r_i_t_y_, _._._.
- Declare that the clauses of specified predicates should nnoott be
- saved to the program. The volatile declaration is normally used
- to avoid that the clauses of dynamic predicates that represent data
- for the current session is saved in the state file.
-
-
- 66..11 LLiimmiittaattiioonnss ooff qqssaavvee__pprrooggrraamm
-
- There are three areas that require special attention when using
- qqssaavvee__pprrooggrraamm//[[11,,22]].
-
- o If the program is an embedded Prolog application or uses the
- foreign language interface, care has to be taken to restore the
- appropriate foreign context. See section 6.2 for details.
-
- o If the program uses directives (:- goal. lines) that perform other
- actions then setting predicate attributes (dynamic, volatile, etc.)
- or loading files (consult, etc.), the directive may need to be
- prefixed with iinniittiiaalliizzaattiioonn//11.
-
- o `Database references as returned by ccllaauussee//33, rreeccoorrddeedd//33, etc. are
- not preserved and may thus not be part of the database when saved.
-
-
- 66..22 RRuunnttiimmeess aanndd FFoorreeiiggnn CCooddee
-
- Some applications may need to use the foreign language interface.
- Object code is by definition machine-dependent and thus cannot be part
- of the saved program file.
-
- To complicate the matter even further there are various ways of loading
- foreign code:
-
- o _U_s_i_n_g _t_h_e _l_i_b_r_a_r_y_(_s_h_l_i_b_) _p_r_e_d_i_c_a_t_e_s
- This is the preferred way of dealing with foreign code. It loads
- quickly and ensures an acceptable level of independence between the
- versions of the emulator and the foreign code loaded. It works
- on Unix machines supporting shared libraries and library functions
- to load them. Most modern Unixes satisfy this constraint.. It
- also works on the Win32 platform: Windows-NT, '95 and Windows 3.1
- running win32s.
-
- o _S_t_a_t_i_c _l_i_n_k_i_n_g
- This mechanism works on all machines, but generally requires the
- same C-compiler and linker to be used for the external code as is
- used to build SWI-Prolog itself. This mechanism is the preferred
- way if shared libraries are not supported.
-
- o _U_s_i_n_g llooaadd__ffoorreeiiggnn//[[22,,55]]
- Basically only works on Unix system supporting the a.out format
- executables. This mechanism is slow and non-portable. It should
- be avoided whenever possible.
-
- To make a runtime executable that can run on multiple platforms one
- must make runtime checks to find the correct way of linking. Suppose
- we have a source-file myextension defining the installation function
- iinnssttaallll(()).
-
- If this file is compiled to a shared library, llooaadd__ffoorreeiiggnn__lliibbrraarryy//11
- will load this library and call the installation function to initialise
- the foreign code. If it is loaded as a static extension, define
- iinnssttaallll(()) as the predicate iinnssttaallll//00:
-
- static foreign_t
- pl_install()
- { install();
-
- PL_succeed;
- }
-
- PL_extension PL_extensions [] =
- {
- /*{ "name", arity, function, PL_FA_<flags> },*/
-
- { "install", 0, pl_install, 0 },
- { NULL, 0, NULL, 0 } /* terminating line */
- };
-
- Now, use the following Prolog code to load the foreign library:
-
- load_foreign_extensions :-
- current_predicate(install, install), !, % static loaded
- install.
- load_foreign_extensions :- % shared library
- load_foreign_library(foreign(myextension)).
-
- :- initialization load_foreign_extensions.
-
- The path alias foreign is defined by ffiillee__sseeaarrcchh__ppaatthh//22. By default
- it searches the directories <_h_o_m_e>/lib/<_a_r_c_h> and <_h_o_m_e>/lib. The
- application can specify additional rules for ffiillee__sseeaarrcchh__ppaatthh//22.
-
-
- 66..33 FFiinnddiinngg AApppplliiccaattiioonn ffiilleess
-
- If your application uses files that are not part of the saved program
- such as database files, configuration files, etc., the runtime version
- has to be able to locate these files. The ffiillee__sseeaarrcchh__ppaatthh//22mechanism
- in combination with the -palias command-line argument is the preferred
- way to locate runtime files. The first step is to define an alias
- for the toplevel directory of your application. We will call this
- directory gnatdir in our examples.
-
- A good place for storing data associated with SWI-Prolog runtime
- systems is below the emulator's home-directory. swi is a predefined
- alias for this directory. The following is a useful default definition
- for the search path.
-
- user:file_search_path(gnatdir, swi(gnat)).
-
- The application should locate all files using absolute_file_name.
- Suppose gnatdir contains a file config.pl to define local
- configuration. Then use the code below to load this file:
-
- configure_gnat :-
- ( absolute_file_name(gnatdir('config.pl'), ConfigFile)
- -> consult(ConfigFile)
- ; format(user_error, 'gnat: Cannot locate config.pl~n'),
- halt(1)
- ).
-
-
- 66..44 UUssiinngg cchhppll ffoorr CCoonnffiigguurraattiioonn IInnffoorrmmaattiioonn
-
-
- 66..44..11 CChhaannggiinngg tthhee eemmuullaattoorr ooff aa rruunnttiimmee aapppplliiccaattiioonn
-
- The program chpl, may be used to manipulate the header of a SWI-Prolog
- bootfile or state created with qqssaavvee__pprrooggrraamm//[[11,,22]].
-
- It will be used most commonly by the installer of a SWI-Prolog runtime
- application to specify the path to the emulator. If the end-user
- decided to install the SWI-Prolog runtime environment in
-
- /usr/local/lib/rt-pl-2.1.4
-
- the gnat application can be told to use this emulator using:
-
- % /usr/local/lib/rtpl-2.1.4/bin/chpl -e /usr/local/lib/rt-pl-
- 2.1.4/bin/pl gnat
-
- Now, gnat may be installed in any public or private directory for
- binaries.
-
-
- 66..44..22 PPaassssiinngg aa ppaatthh ttoo tthhee aapppplliiccaattiioonn
-
- Suppose the system administrator has installed the SWI-Prolog
- runtime environment in /usr/local/lib/rt-pl-2.1.4. A user wants
- to install gnat, but gnat will look for its configuration in
- /usr/local/lib/rt-pl-2.1.4/gnat where the user cannot write.
-
- The user decides to install the gnat runtime files in
- /users/bob/lib/gnat. For one-time usage, the user may decide
- to start gnat using the command:
-
- % gnat -p gnatdir=/users/bob/lib/gnat
-
- For a more widely used executable, this is not very comfortable. The
- user may decide to edit the shell-script part of gnat. Upto the line
- holding
-
- # End Header
-
- gnat is a simple /bin/sh script. After this line, the file is binary
- and may contain long lines. Most editors are not capable of editing
- such files. Instead of editing the file directly, the program cchhppll((1))
- may be used to extract and replace the header of gnat. The following
- editing sequence will work with any editor capable of editing ASCII
- files.
-
- % chpl -x gnat > gnat.hdr
- % emacs gnat.hdr
- % chpl -h gnat.hdr gnat
-
- The header may be changed to the following to install gnat properly:
-
- #!/bin/sh
- # SWI-Prolog version: 2.1.4
- # SWI-Prolog save-version: 25
- exec ${SWIPL-/usr/local/lib/rt-pl-2.1.4/bin/pl} -x $0 \
- -p gnatdir=/users/bob/lib/gnat "$@"
-
-
- 66..55 TThhee RRuunnttiimmee EEnnvviirroonnmmeenntt
-
-
- 66..55..11 TThhee RRuunnttiimmee EEmmuullaattoorr
-
- The sources may be used to built two versions of the emulator. By
- default, the _d_e_v_e_l_o_p_m_e_n_t _e_m_u_l_a_t_o_r is built. This emulator contains
- all features for interactive development of Prolog applications. If
- the system is configured using --enable-runtime, mmaakkee((1)) will create a
- _r_u_n_t_i_m_e _v_e_r_s_i_o_n of the emulator. This emulator is equivalent to the
- development version, except for the following features:
-
- o _N_o _i_n_p_u_t _e_d_i_t_i_n_g
- The GNU library -lreadline that provides EMACS compatible editing
- of input lines will not be linked to the system.
-
- o _N_o _t_r_a_c_e_r
- The tracer and all its options are removed, making the system a
- little faster too.
-
- o _N_o _p_r_o_f_i_l_e_r
- pprrooffiillee//33 and friends are not supported. This saves some space and
- provides better performance.
-
- o _N_o _i_n_t_e_r_r_u_p_t
- Keyboard interrupt (Control-C normally) is not rebound and will
- normally terminate the application.
-
- o _f_e_a_t_u_r_e_(_r_u_n_t_i_m_e_, _t_r_u_e_) _s_u_c_c_e_e_d_s
- This may be used to verify your application is running in the
- runtime environment rather than the development environment.
-
- o ccllaauussee//[[22,,33]] _d_o _n_o_t _w_o_r_k _o_n _s_t_a_t_i_c _p_r_e_d_i_c_a_t_e_s
- This feature inhibits listing your program. It is only a very
- limited protection however.
-
- The following fragment is an example for building the runtime
- environment in HOME/lib/rt-pl-2.1.4. If possible, the shared-library
- interface should be configured to ensure it can serve a large number of
- applications.
-
- % cd pl-2.1.4
- % mkdir runtime
- % cd runtime
- % ../src/configure --enable-runtime --prefix=$HOME
- % make
- % make rt-install
-
- The runtime directory contains the components listed below. This
- directory may be tar'ed and shipped with your application.
-
- ________________________________________________
- |_README.RT__|Info_on_the_runtime_environment___|
- | bin/pl |The emulator itself |
-
- |_bin/chpl___|The_utility_to_change_the_runtime_|
- | man/chpl.1 |Manual page for chpl |
- |_man/pl.1___|Manual_page_for_pl________________|
- |_swipl______|pointer_to_the_home_directory_(.)_|
- | lib/ |directory for shared libraries |
- |_lib/<_a_r_c_h>/|machine-specific_shared_libraries_|
-
-
- CChhaapptteerr 77.. HHAACCKKEERRSS CCOORRNNEERR
-
- This appendix describes a number of predicates which enable the
- Prolog user to inspect the Prolog environment and manipulate (or
- even redefine) the debugger. They can be used as entry points for
- experiments with debugging tools for Prolog. The predicates described
- here should be handled with some care as it is easy to corrupt the
- consistency of the Prolog system by misusing them.
-
-
- 77..11 EExxaammiinniinngg tthhee EEnnvviirroonnmmeenntt SSttaacckk
-
-
- pprroolloogg__ccuurrrreenntt__ffrraammee((_-_F_r_a_m_e))
- Unify _F_r_a_m_e with an integer providing a reference to the
- parent of the current local stack frame. A pointer to the
- current local frame cannot be provided as the predicate succeeds
- deterministically and therefore its frame is destroyed immediately
- after succeeding.
-
-
- pprroolloogg__ffrraammee__aattttrriibbuuttee((_+_F_r_a_m_e_, _+_K_e_y_, _-_V_a_l_u_e))
- Obtain information about the local stack frame _F_r_a_m_e. _F_r_a_m_e
- is a frame reference as obtained through pprroolloogg__ccuurrrreenntt__ffrraammee//11,
- pprroolloogg__ttrraaccee__iinntteerrcceeppttiioonn//44or this predicate. The key values are
- described below.
-
- aalltteerrnnaattiivvee
- _V_a_l_u_e is unified with an integer reference to the local stack
- frame in which execution is resumed if the goal associated
- with _F_r_a_m_e fails. Fails if the frame has no alternative
- frame.
-
- hhaass__aalltteerrnnaattiivveess
- _V_a_l_u_e is unified with true if _F_r_a_m_e still is a candidate for
- backtracking. false otherwise.
-
- ggooaall
- _V_a_l_u_e is unified with the goal associated with _F_r_a_m_e. If the
- definition module of the active predicate is not user the goal
- is represented as <_m_o_d_u_l_e>:<_g_o_a_l>. Do not instantiate variables
- in this goal unless you kknnooww what you are doing!
-
- ccllaauussee
- _V_a_l_u_e is unified with a reference to the currently running
- clause. Fails if the current goal is associated with a
- foreign (C) defined predicate. See also nntthh__ccllaauussee//33 and
- ccllaauussee__pprrooppeerrttyy//22.
-
- lleevveell
- _V_a_l_u_e is unified with the recursion level of _F_r_a_m_e. The top
- level frame is at level `0'.
-
- ppaarreenntt
- _V_a_l_u_e is unified with an integer reference to the parent local
- stack frame of _F_r_a_m_e. Fails if _F_r_a_m_e is the top frame.
-
- ccoonntteexxtt__mmoodduullee
- _V_a_l_u_e is unified with the name of the context module of the
- environment.
-
- ttoopp
- _V_a_l_u_e is unified with true if _F_r_a_m_e is the top Prolog goal
- from a recursive call back from the foreign language. false
- otherwise.
-
- hhiiddddeenn
- _V_a_l_u_e is unified with true if the frame is hidden from the
- user, either because a parent has the hide-childs attribute
- (all system predicates), or the system has no trace-me
- attribute.
-
- ppcc
- _V_a_l_u_e is unified with the program-pointer saved on behalve of
- the parent-goal if the parent-goal is not owned by a foreign
- predicate.
-
- aarrgguummeenntt((_N))
- _V_a_l_u_e is unified with the _N-th slot of the frame. Argument
- 1 is the first argument of the goal. Arguments above the
- arity refer to local variables. Fails silently if _N is out of
- range.
-
-
- 77..22 IInntteerrcceeppttiinngg tthhee TTrraacceerr
-
-
- pprroolloogg__ttrraaccee__iinntteerrcceeppttiioonn((_+_P_o_r_t_, _+_F_r_a_m_e_, _+_P_C_, _-_A_c_t_i_o_n))
- Dynamic predicate, normally not defined. This predicate is called
- from the SWI-Prolog debugger just before it would show a port. If
- this predicate succeeds the debugger assumes the trace action has
- been taken care of and continues execution as described by _A_c_t_i_o_n.
- Otherwise the normal Prolog debugger actions are performed.
-
- _P_o_r_t is one of call, redo, exit, fail or unify. _F_r_a_m_e is an
- integer reference to the current local stack frame. _P_C is the
- current value of the program-counter, relative to the start of
- the current clause, or 0 if it is invalid, for example because
- the current frame runs a foreign predicate, or no clause has been
- selected yet. _A_c_t_i_o_n should be unified with one of the atoms
- continue (just continue execution), retry (retry the current goal)
- or fail (force the current goal to fail). Leaving it a variable is
- identical to continue.
-
- Together with the predicates described in section 3.37 and the
- other predicates of this chapter this predicate enables the Prolog
- user to define a complete new debugger in Prolog. Besides this it
- enables the Prolog programmer monitor the execution of a program.
- The example below records all goals trapped by the tracer in the
- database.
-
- prolog_trace_interception(Port, Frame, _PC, continue) :-
- prolog_frame_attribute(Frame, goal, Goal),
- prolog_frame_attribute(Frame, level, Level),
- recordz(trace, trace(Port, Level, Goal)).
-
- To trace the execution of `go' this way the following query should
- be given:
-
- ?- trace, go, notrace.
-
-
- pprroolloogg__sskkiipp__lleevveell((_-_O_l_d_, _+_N_e_w))
- Unify _O_l_d with the old value of `skip level' and than set this
- level according to _N_e_w. New is an integer, or the special atom
- very_deep (meaning don't skip). The `skip level' is a global
- variable of the Prolog system that disables the debugger on all
- recursion levels deeper than the level of the variable. Used to
- implement the trace options `skip' (sets skip level to the level
- of the frame) and `up' (sets skip level to the level of the parent
- frame (i.e. the level of this frame minus 1).
-
-
- 77..33 EExxcceeppttiioonn HHaannddlliinngg
-
- A start has been made to make exception handling available to the
- Prolog user. On exceptions a dynamic and multifile defined predicate
- eexxcceeppttiioonn//33 is called. If this user defined predicate succeeds Prolog
- assumes the exception has been taken care of. Otherwise the system
- default exception handler is called.
-
-
- eexxcceeppttiioonn((_+_E_x_c_e_p_t_i_o_n_, _+_C_o_n_t_e_x_t_, _-_A_c_t_i_o_n))
- Dynamic predicate, normally not defined. Called by the Prolog
- system on run-time exceptions. Currently eexxcceeppttiioonn//33 is only used
- for trapping undefined predicates. Future versions might handle
- signal handling, floating exceptions and other runtime errors via
- this mechanism. The values for _E_x_c_e_p_t_i_o_n are described below.
-
- uunnddeeffiinneedd__pprreeddiiccaattee
- If _E_x_c_e_p_t_i_o_n is undefined_predicate _C_o_n_t_e_x_t is instantiated to
- a term _N_a_m_e/_A_r_i_t_y. _N_a_m_e refers to the name and _A_r_i_t_y to the
- arity of the undefined predicate. If the definition module
- of the predicate is not _u_s_e_r, _C_o_n_t_e_x_t will be of the form
- <_M_o_d_u_l_e>:<_N_a_m_e>/<_A_r_i_t_y>. If the predicate fails Prolog will
- print the default error warning and start the tracer. If
- the predicate succeeds it should instantiate the last argument
- either to the atom fail to tell Prolog to fail the predicate
- or the atom retry to tell Prolog to retry the predicate. This
- only makes sense if the exception handler has defined the
- predicate. Otherwise it will lead to a loop.
-
- wwaarrnniinngg
- If prolog wants to give a warning while reading a file, it
- will first raise the exception _w_a_r_n_i_n_g. The context argument
- is a term of the form warning(<_P_a_t_h>, <_L_i_n_e_N_o>, <_M_e_s_s_a_g_e>),
- where _P_a_t_h is the absolute filename of the file prolog is
- reading; _L_i_n_e_N_o is an estimate of the line number where the
- error occurred and _M_e_s_s_a_g_e is a Prolog string indicating the
- message. The _A_c_t_i_o_n argument is ignored. The error is
- supposed to be presented to the user if the exception handler
- succeeds. Otherwise the standard Prolog warning message is
- printed.
-
- This exception is used by the library(emacs_interface), that
- integrates error handling with GNU Emacs.
-
-
- 77..44 RReeaaddlliinnee IInntteerraaccttiioonn
-
- The following predicates are available if feature(readline, true)
- succeeds. They allow for direct interaction with the GNU readline
- library. See also rreeaaddlliinnee((3))
-
-
- rrll__rreeaadd__iinniitt__ffiillee((_+_F_i_l_e))
- Read a readline initialisation file. Readline by default reads
- ~/.inputrc. This predicate may be used to read alternative
- readline initialisation files.
-
-
- rrll__aadddd__hhiissttoorryy((_+_L_i_n_e))
- Add a line to the Control-P/Control-N history system of the
- readline library.
-
-
- CChhaapptteerr 88.. SSUUMMMMAARRYY
-
-
- 88..11 PPrreeddiiccaatteess
-
- The predicate summary is used by the Prolog predicate aapprrooppooss//11 to
- suggest predicates from a keyword.
-
- !/0 Cut (discard choicepoints)
- !/1 Cut block. See bblloocckk//33
- ,/2 Conjunction of goals
- ->/2 If-then-else
- *->/2 Soft-cut
- ./2 Consult. Also list constructor
- ;/2 Disjunction of goals. Same as |//22
- </2 Arithmetic smaller
-
- =/2 Unification
- =../2 ``Univ.'' Term to list conversion
- =:=/2 Arithmetic equal
- =</2 Arithmetic smaller or equal
- ==/2 Identical
- =@=/2 Structural identical
- =\=/2 Arithmetic not equal
-
- >/2 Arithmetic larger
- >=/2 Arithmetic larger or equal
- @</2 Standard order smaller
- @=</2 Standard order smaller or equal
- @>/2 Standard order larger
- @>=/2 Standard order larger or equal
- \+/1 Negation by failure. Same as nnoott//11
- \=/2 Not unifyable
-
- \==/2 Not identical
- \=@=/2 Not structural identical
- ^/2 Existential quantification (bbaaggooff//33, sseettooff//33)
- |/2 Disjunction of goals. Same as ;//22
- abolish/1 Remove predicate definition from the database
- abolish/2 Remove predicate definition from the database
- abort/0 Abort execution, return to top level
-
- absolute_file_name/2 Get absolute path name
- absolute_file_name/3 Get absolute path name with options
- access_file/2 Check access permissions of a file
- append/1 Append to a file
- append/3 Concatenate lists
- apply/2 Call goal with additional arguments
- apropos/1 library(online_help) Show related predicates and manual sections
- arg/3 Access argument of a term
-
- arithmetic_function/1 Register an evaluable function
- assert/1 Add a clause to the database
- assert/2 Add a clause to the database, give reference
- asserta/1 Add a clause to the database (first)
- asserta/2 Add a clause to the database (first)
- assertz/1 Add a clause to the database (last)
- assertz/2 Add a clause to the database (last)
-
- at_end_of_stream/0 Test for end of file on input
- at_end_of_stream/1 Test for end of file on stream
- at_halt/1 Register goal to run at hhaalltt//11
- at_initialization/1 Register goal to run at start-up
- atom/1 Type check for an atom
- atom_char/2 Convert between atom and ASCII value
- atom_chars/2 Convert between atom and list of ASCII values
- atom_length/2 Determine length of an atom
-
- atom_prefix/2 Test for start of atom
- atom_to_term/3 Convert between atom and term
- atomic/1 Type check for primitive
- autoload/0 Autoload all predicates now
- bagof/3 Find all solutions to a goal
- between/3 Integer range checking/generating
- block/3 Start a block (`catch'/`throw')
-
- break/0 Start interactive toplevel
- call/1 Call a goal
- call/[2..] Call with additional arguments
- call_dll_function/2 Win32: Call function in dynamic link library (.dll file)
- call_shared_object_function/2 UNIX: Call C-function in shared (.so) file
- call_with_depth_limit/3 Prove goal with bounded depth
- catch/3 Call goal, watching for exceptions
- character_count/2 Get character index on a stream
-
- chdir/1 Change working directory
- checklist/2 Invoke goal on all members of a list
- clause/2 Get clauses of a predicate
- clause/3 Get clauses of a predicate
- clause_property/2 Get properties of a clause
- close/1 Close stream
- close_dde_conversation/1 Win32: Close DDE channel
-
- close_dll/1 Win32: Close dynamic link library (.dll file)
- close_shared_object/1 UNIX: Close shared library (.so file)
- compare/3 Compare, using a predicate to determine the order
- compiling/0 Is this a compilation run?
- compound/1 Test for compound term
- concat/3 Append two atoms
- concat_atom/2 Append a list of atoms
- concat_atom/3 Append a list of atoms with separator
-
- consult/1 Read (compile) a Prolog source file
- context_module/1 Get context module of current goal
- convert_time/8 Convert time stamp
- copy_term/2 Make a copy of a term
- current_arithmetic_function/1 Examine evaluable functions
- current_atom/1 Examine existing atoms
- current_flag/1 Examine existing flags
-
- current_foreign_library/2 library(shlib) Examine loaded shared libraries (.so files)
- current_functor/2 Examine existing name/arity pairs
- current_input/1 Get current input stream
- current_key/1 Examine existing database keys
- current_module/1 Examine existing modules
- current_module/2 Examine existing modules
- current_op/3 Examine current operator declarations
- current_output/1 Get the current output stream
-
- current_predicate/2 Examine existing predicates
- current_stream/3 Examine open streams
- dde_current_connection/2 Win32: Examine open DDE connections
- dde_current_service/2 Win32: Examine DDE services provided
- dde_execute/2 Win32: Execute command on DDE server
- dde_register_service/2 Win32: Become a DDE server
- dde_request/3 Win32: Make a DDE request
-
- dde_poke/3 Win32: POKE operation on DDE server
- dde_unregister_service/1 Win32: Terminate a DDE service
- debug/0 Test for debugging mode
- debugging/0 Show debugger status
- default_module/2 Get the default modules of a module
- delete/3 Delete all matching members from a list
- delete_file/1 Remove a file from the file system
- discontiguous/1 Indicate distributed definition of a predicate
-
- dup_stream/2 Duplicate I/O streams
- dwim_match/2 Atoms match in ``Do What I Mean'' sense
- dwim_match/3 Atoms match in ``Do What I Mean'' sense
- dwim_predicate/2 Find predicate in ``Do What I Mean'' sense
- dynamic/1 Indicate predicate definition may change
- ed/0 Edit last edited predicate
- ed/1 Edit a predicate
-
- edit/0 Edit last edited file
- edit/1 Edit a file
- edit_source/1 (hook) Intercept editing
- ensure_loaded/1 Consult a file if that has not yet been done
- erase/1 Erase a database record or clause
- exception/3 (hook) Handle runtime exceptions
- exists_directory/1 Check existence of directory
- exists_file/1 Check existence of file
-
- exit/2 Exit from named block. See bblloocckk//33
- expand_answer/2 Expand answer of query
- expand_file_name/2 Wildcard expansion of file names
- expand_file_search_path/2 Wildcard expansion of file paths
- expand_query/4 Expanded entered query
- expand_term/2 Compiler: expand read term into clause(s)
- explain/1 library(explain) Explain argument
-
- explain/2 library(explain) 2nd argument is explanation of first
- export/1 Export a predicate from a module
- export_list/2 List of public predicates of a module
- fail/0 Always false
- fail/1 Immediately fail named block. See bblloocckk//33
- feature/2 Get system configuration parameters
- file_base_name/2 Get file part of path
- file_directory_name/2 Get directory part of path
-
- file_name_extension/3 Add, remove or test file extensions
- file_search_path/2 Define path-aliases for locating files
- fileerrors/2 Do/Don't warn on file errors
- findall/3 Find all solutions to a goal
- flag/3 Simple global variable system
- flatten/2 Transform nested list into flat list
- float/1 Type check for a floating point number
-
- flush/0 Output pending characters on current stream
- flush_output/1 Output pending characters on specified stream
- forall/2 Prove goal for all solutions of another goal
- foreign_file/1 Examine loaded foreign files
- format/1 Formatted output
- format/2 Formatted output with arguments
- format/3 Formatted output on a stream
- format_predicate/2 Program ffoorrmmaatt//[[11,,22]]
-
- free_variables/2 Find unbound variables in a term
- functor/3 Get name and arity of a term or construct a term
- garbage_collect/0 Invoke the garbage collector
- gensym/2 Generate unique atoms from a base
- get/1 Read first non-blank character
- get/2 Read first non-blank character from a stream
- get0/1 Read next character
-
- get0/2 Read next character from a stream
- get_single_char/1 Read next character from the terminal
- get_time/1 Get current time
- getenv/2 Get shell environment variable
- ground/1 Verify term holds no unbound variables
- halt/0 Exit from Prolog
- halt/1 Exit from Prolog with status
- hash_term/2 Hash-value of ground term
-
- help/0 Give help on help
- help/1 Give help on predicates and show parts of manual
- ignore/1 Call the argument, but always succeed
- import/1 Import a predicate from a module
- index/1 Change clause indexing
- initialization/1 Initialization directive
- int_to_atom/2 Convert from integer to atom
-
- int_to_atom/3 Convert from integer to atom (non-decimal)
- integer/1 Type check for integer
- intersection/3 Set intersection
- is/2 Evaluate arithmetic expression
- is_absolute_file_name/1 True if arg defines an absolute path
- is_list/1 Type check for a list
- is_set/1 Type check for a set
- keysort/2 Sort, using a key
-
- last/2 Last element of a list
- leash/1 Change ports visited by the tracer
- length/2 Length of a list
- library_directory/1 (hook) Directories holding Prolog libraries
- limit_stack/2 Limit stack expansion
- line_count/2 Line number on stream
- line_position/2 Character position in line on stream
-
- list_to_set/2 Remove duplicates
- listing/0 List program in current module
- listing/1 List predicate
- load_files/2 Load source files with options
- load_foreign/2 Load foreign (C) module
- load_foreign/5 Load foreign (C) module
- load_foreign_library/1 library(shlib) Load shared library (.so file)
- load_foreign_library/2 library(shlib) Load shared library (.so file)
-
- make/0 Reconsult all changed source files
- make_fat_filemap/1 Win32: Create file containing non-FAT filenames
- make_library_index/1 Create autoload file INDEX.pl
- maplist/3 Transform all elements of a list
- member/2 Element is member of a list
- memberchk/2 Deterministic mmeemmbbeerr//22
- merge/3 Merge two sorted lists
-
- merge_set/3 Merge two sorted sets
- message_hook/3 Intercept pprriinntt__mmeessssaaggee//22
- meta_predicate/1 Quintus compatibility
- module/1 Query/set current type-in module
- module/2 Declare a module
- module_transparent/1 Indicate module based meta predicate
- msort/2 Sort, do not remove duplicates
- multifile/1 Indicate distributed definition of predicate
-
- name/2 Convert between atom and list of ASCII characters
- nl/0 Generate a newline
- nl/1 Generate a newline on a stream
- nodebug/0 Disable debugging
- nonvar/1 Type check for bound term
- noprotocol/0 Disable logging of user interaction
- nospy/1 Remove spy point
-
- nospyall/0 Remove all spy points
- not/1 Negation by failure (argument not provable). Same as \+//11
- notrace/0 Stop tracing
- notrace/1 Do not debug argument goal
- nth0/3 N-th element of a list (0-based)
- nth1/3 N-th element of a list (1-based)
- nth_clause/3 N-th clause of a predicate
- number/1 Type check for integer or float
-
- number_chars/2 Convert between number and atom
- numbervars/4 Enumerate unbound variables of a term using a given base
- once/1 Call a goal deterministically
- op/3 Declare an operator
- open/3 Open a file (creating a stream)
- open/4 Open a file (creating a stream)
- open_dde_conversation/3 Win32: Open DDE channel
-
- open_null_stream/1 Open a stream to discard output
- open_shared_object/2 UNIX: Open shared library (.so file)
- open_shared_object/3 UNIX: Open shared library (.so file)
- peek_byte/1 Read character without removing
- peek_byte/2 Read character without removing
- phrase/2 Activate grammar-rule set
- phrase/3 Activate grammar-rule set (returning rest)
- please/3 Query/change environment parameters
-
- plus/3 Logical integer addition
- portray/1 (hook) Modify behaviour of pprriinntt//11
- portray_clause/1 Pretty print a clause
- predicate_property/2 Query predicate attributes
- predsort/3 Sort, using a predicate to determine the order
- preprocessor/2 Install a preprocessor before the compiler
- print/1 Print a term
-
- print/2 Print a term on a stream
- print_message/2 Print message from (exception) term
- profile/3 Obtain execution statistics
- profile_count/3 Obtain profile results on a predicate
- profiler/2 Obtain/change status of the profiler
- prolog/0 Run interactive toplevel
- prolog_current_frame/1 Reference to goal's environment stack
- prolog_frame_attribute/3 Obtain information on a goal environment
-
- prolog_load_context/2 Context information for directives
- prolog_skip_level/2 Indicate deepest recursion to trace
- prolog_to_os_filename/2 Convert between Prolog and OS filenames
- prolog_trace_interception/4 library(user) Intercept the Prolog tracer
- prompt1/1 Change prompt for 1 line
- prompt/2 Change the prompt used by rreeaadd//11
- proper_list/1 Type check for list
-
- protocol/1 Make a log of the user interaction
- protocola/1 Append log of the user interaction to file
- protocolling/1 On what file is user interaction logged
- put/1 Write a character
- put/2 Write a character on a stream
- qcompile/1 Compile source to Quick Load File
- qload/1 Load Quick Load File as ccoonnssuulltt//11
- qsave_program/1 Create runtime application
-
- qsave_program/2 Create runtime application
- read/1 Read Prolog term
- read/2 Read Prolog term from stream
- read_clause/1 Read clause
- read_clause/2 Read clause from stream
- read_history/6 Read using history substitution
- read_link/3 Read a symbolic link
-
- read_term/2 Read term with options
- read_term/3 Read term with options from stream
- read_variables/2 Read clause including variable names
- read_variables/3 Read clause including variable names from stream
- recorda/2 Record term in the database (first)
- recorda/3 Record term in the database (first)
- recorded/2 Obtain term from the database
- recorded/3 Obtain term from the database
-
- recordz/2 Record term in the database (last)
- recordz/3 Record term in the database (last)
- redefine_system_predicate/1 Abolish system definition
- rename_file/2 Change name of file
- repeat/0 Succeed, leaving infinite backtrack points
- require/1 This file requires these predicates
- reset_profiler/0 Clear statistics obtained by the profiler
-
- restore/1 Restore saved-state (ssaavvee//11, ssaavvee__pprrooggrraamm//11)
- retract/1 Remove clause from the database
- retractall/1 Remove unifying clauses from the database
- reverse/2 Inverse the order of the elements in a list
- same_file/2 Succeeds if arguments refer to same file
- save/1 Save program including current goal
- save/2 Save program including current goal
- save_program/1 Save the current program on a file
-
- save_program/2 Save the current program on a file
- see/1 Change the current input stream
- seeing/1 Query the current input stream
- seen/0 Close the current input stream
- select/3 Select element of a list
- set_feature/2 Define a system feature
- set_input/1 Set current input stream from a stream
-
- set_output/1 Set current output stream from a stream
- set_tty/2 Set `tty' stream
- setarg/3 Destructive assignment on term
- setenv/2 Set shell environment variable
- setof/3 Find all unique solutions to a goal
- sformat/2 Format on a string
- sformat/3 Format on a string
- shell/0 Execute interactive subshell
-
- shell/1 Execute OS command
- shell/2 Execute OS command
- show_profile/1 Show results of the profiler
- size_file/2 Get size of a file in characters
- skip/1 Skip to character in current input
- skip/2 Skip to character on stream
- rl_add_history/1 Add line to readline(3) history
-
- rl_read_init_file/1 Read readline(3) init file
- sleep/1 Suspend execution for specified time
- sort/2 Sort elements in a list
- source_file/1 Examine currently loaded source files
- source_file/2 Obtain source file of predicate
- source_location/2 Location of last read term
- spy/1 Force tracer on specified predicate
- stack_parameter/4 Some systems: Query/Set runtime stack parameter
-
- statistics/0 Show execution statistics
- statistics/2 Obtain collected statistics
- stream_position/3 Get/seek to position in file
- string/1 Type check for string
- string_concat/3 ccoonnccaatt//33 for strings (non-deterministic)
- string_length/2 Determine length of a string
- string_to_atom/2 Conversion between string and atom
-
- string_to_list/2 Conversion between string and list of ASCII
- style_check/1 Change level of warnings
- sublist/3 Determine elements that meet condition
- subset/2 Generate/check subset relation
- substring/4 Get part of a string
- subtract/3 Delete elements that do not meet condition
- succ/2 Logical integer successor relation
- swritef/2 Formatted write on a string
-
- swritef/3 Formatted write on a string
- tab/1 Output number of spaces
- tab/2 Output number of spaces on a stream
- tell/1 Change current output stream
- telling/1 Query current output stream
- term_expansion/2 (hook) Convert term before compilation
- term_to_atom/2 Convert between term and atom
-
- throw/1 Raise an exception (see ccaattcchh//33)
- time/1 Determine time needed to execute goal
- time_file/2 Get last modification time of file
- tmp_file/2 Create a temporary filename
- told/0 Close current output
- trace/0 Start the tracer
- trace/1 Set trace-point on predicate
- trace/2 Set/Clear trace-point on ports
-
- tracing/0 Query status of the tracer
- trim_stacks/0 Release unused memory resources
- true/0 Succeed
- tty_get_capability/3 Get terminal parameter
- tty_goto/2 Goto position on screen
- tty_put/2 Write control string to terminal
- ttyflush/0 Flush output on terminal
-
- union/3 Union of two sets
- unknown/2 Trap undefined predicates
- unload_foreign_library/1 library(shlib) Detach shared library (.so file)
- unsetenv/1 Delete shell environment variable
- use_module/1 Import a module
- use_module/2 Import predicates from a module
- var/1 Type check for unbound variable
- visible/1 Ports that are visible in the tracer
-
- volatile/1 Predicates that are not saved
- wait_for_input/3 Wait for input with optional timeout
- wildcard_match/2 Csh(1) style wildcard match
- win_exec/2 Win32: spawn Windows task
- write/1 Write term
- write/2 Write term to stream
- write_ln/1 Write term, followed by a newline
-
- write_canonical/1 Write a term with quotes, ignore operators
- write_canonical/2 Write a term with quotes, ignore operators on a stream
- write_term/2 Write term with options
- write_term/3 Write term with options to stream
- writef/1 Formatted write
- writef/2 Formatted write on stream
- writeq/1 Write term, insert quotes
- writeq/2 Write term, insert quotes on stream
-
-
- 88..22 AArriitthhmmeettiicc FFuunnccttiioonnss
-
- */2 Multiplication
- **/2 Power function
-
- +/2 Addition
- -/1 Unary minus
- -/2 Subtraction
- //2 Division
- ///2 Integer division
- /\/2 Bitwise and
- <</2 Bitwise left shift
- >>/2 Bitwise right shift
-
- ./2 List of one character: character code
- \/1 Bitwise negation
- \//2 Bitwise or
- ^/2 Power function
- abs/1 Absolute value
- acos/1 Inverse (arc) cosine
- asin/1 Inverse (arc) sine
-
- atan/1 Inverse (arc) tangent
- atan/2 Rectangular to polar conversion
- ceil/1 Smallest integer larger than arg
- ceiling/1 Smallest integer larger than arg
- cos/1 Cosine
- cputime/0 Get CPU time
- e/0 Mathematical constant
- exp/1 Exponent (base e)
-
- float/1 Explicitly convert to float
- float_fractional_part/1 Fractional part of a float
- float_integer_part/1 Integer part of a float
- floor/1 Largest integer below argument
- integer/1 Round to nearest integer
- log/1 Natural logarithm
- log10/1 10 base logarithm
-
- max/2 Maximum of two numbers
- min/2 Minimum of two numbers
- mod/2 Remainder of division
- random/1 Generate random number
- rem/2 Remainder of division
- round/1 Round to nearest integer
- truncate/1 Truncate float to integer
- pi/0 Mathematical constant
-
- sign/1 Extract sign of value
- sin/1 Sine
- sqrt/1 Square root
- tan/1 Tangent
- xor/2 Bitwise exclusive or
-
-
- 88..33 OOppeerraattoorrss
-
- $ 1 fx Bind toplevel variable
- ^ 200 xfy Predicate
- ^ 200 xfy Arithmetic function
- mod 300 xfx Arithmetic function
- * 400 yfx Arithmetic function
- / 400 yfx Arithmetic function
- // 400 yfx Arithmetic function
- << 400 yfx Arithmetic function
-
- >> 400 yfx Arithmetic function
- xor 400 yfx Arithmetic function
- + 500 fx Arithmetic function
- - 500 fx Arithmetic function
- ? 500 fx XPCE: obtainer
- \ 500 fx Arithmetic function
- + 500 yfx Arithmetic function
-
- - 500 yfx Arithmetic function
- /\ 500 yfx Arithmetic function
- \/ 500 yfx Arithmetic function
- : 600 xfy module:term separator
- < 700 xfx Predicate
- = 700 xfx Predicate
- =.. 700 xfx Predicate
- =:= 700 xfx Predicate
-
- < 700 xfx Predicate
- == 700 xfx Predicate
- =@= 700 xfx Predicate
- =\= 700 xfx Predicate
- > 700 xfx Predicate
- >= 700 xfx Predicate
- @< 700 xfx Predicate
-
- @=< 700 xfx Predicate
- @> 700 xfx Predicate
- @>= 700 xfx Predicate
- is 700 xfx Predicate
- \= 700 xfx Predicate
- \== 700 xfx Predicate
- =@= 700 xfx Predicate
- not 900 fy Predicate
-
- \+ 900 fy Predicate
- , 1000 xfy Predicate
- -> 1050 xfy Predicate
- *-> 1050 xfy Predicate
- ; 1100 xfy Predicate
- | 1100 xfy Predicate
- discontiguous 1150 fx Predicate
-
- dynamic 1150 fx Predicate
- module_transparent 1150 fx Predicate
- multifile 1150 fx Predicate
- volatile 1150 fx Predicate
- initialization 1150 fx Predicate
- :- 1200 fx Introduces a directive
- ?- 1200 fx Introduces a directive
- --> 1200 xfx DCGrammar: rewrite
-
- :- 1200 xfx head :- body. separator
-
-
- Bibliography
-
- [Anjewierden & Wielemaker, 1989] A. Anjewierden and J. Wielemaker.
- Extensible objects. ESPRIT Project
- 1098 Technical Report UvA-C1-TR-006a,
- University of Amsterdam, March 1989.
-
- [BIM, 1989] _B_I_M _P_r_o_l_o_g _r_e_l_e_a_s_e _2_._4. Everberg,
- Belgium, 1989.
-
- [Bowen & Byrd, 1983] D. L. Bowen and L. M. Byrd. A portable
- Prolog compiler. In L. M. Pereira,
- editor, _P_r_o_c_e_e_d_i_n_g_s _o_f _t_h_e _L_o_g_i_n
- _P_r_o_g_r_a_m_m_i_n_g _W_o_r_k_s_h_o_p _1_9_8_3, Lisabon,
- Portugal, 1983. Universidade nova de
- Lisboa.
-
- [Bratko, 1986] I. Bratko. _P_r_o_l_o_g _P_r_o_g_r_a_m_m_i_n_g _f_o_r _A_r_-
- _t_i_f_i_c_i_a_l _I_n_t_e_l_l_i_g_e_n_c_e. Addison-Wesley,
- Reading, Massachusetts, 1986.
-
- [Clocksin & Melish, 1987] W. F. Clocksin and C. S. Melish.
- _P_r_o_g_r_a_m_m_i_n_g _i_n _P_r_o_l_o_g. Springer-
- Verlag, New York, Third, Revised and
- Extended edition, 1987.
-
- [Deransart _e_t _a_l_., 1996] P. Deransart, A. Ed-Dbali, and
- L. Cervoni. _P_r_o_l_o_g_: _T_h_e _S_t_a_n_d_a_r_d.
- Springer-Verlag, New York, 1996.
-
- [Kernighan & Ritchie, 1978] B. W. Kernighan and D. M. Ritchie. _T_h_e
- _C _P_r_o_g_r_a_m_m_i_n_g _L_a_n_g_u_a_g_e. Prentice-Hall,
- Englewood Cliffs, New Jersey, 1978.
-
- [OKeefe, 1990] R. A. OKeefe. _T_h_e _C_r_a_f_t _o_f _P_r_o_l_o_g.
- MIT Press, Massachussetts, 1990.
-
- [Pereira, 1986] F. Pereira. _C_-_P_r_o_l_o_g _U_s_e_r_'_s _M_a_n_u_a_l,
- 1986.
-
- [Qui, 1997] _Q_u_i_n_t_u_s _P_r_o_l_o_g_, _U_s_e_r _G_u_i_d_e _a_n_d
- _R_e_f_e_r_e_n_c_e _M_a_n_u_a_l. Berkhamsted, UK,
- 1997.
-
- [Sterling & Shapiro, 1986] L. Sterling and E. Shapiro. _T_h_e
- _A_r_t _o_f _P_r_o_l_o_g. MIT Press, Cambridge,
- Massachusetts, 1986.
-
- [Warren, 1983] D. H. D. Warren. The runtime
- environment for a prolog compiler
- using a copy algorithm. Technical
- Report 83/052, SUNY and Stone Brook,
- New York, 1983. Major revision March
- 1984.
-
- 722
-